home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / shk.c < prev    next >
C/C++ Source or Header  |  1993-01-22  |  80KB  |  3,109 lines

  1. /*    SCCS Id: @(#)shk.c    3.1    93/01/12    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "eshk.h"
  7.  
  8. /*#define DEBUG*/
  9.  
  10. #define PAY_SOME    2
  11. #define PAY_BUY     1
  12. #define PAY_CANT    0    /* too poor */
  13. #define PAY_SKIP  (-1)
  14. #define PAY_BROKE (-2)
  15.  
  16. #ifdef KOPS
  17. STATIC_DCL void FDECL(makekops, (coord *));
  18. STATIC_DCL void FDECL(call_kops, (struct monst *,BOOLEAN_P));
  19. # ifdef OVLB
  20. static void FDECL(kops_gone, (BOOLEAN_P));
  21. # endif /* OVLB */
  22. #endif /* KOPS */
  23.  
  24. #define IS_SHOP(x)    (rooms[x].rtype >= SHOPBASE)
  25.  
  26. extern const struct shclass shtypes[];    /* defined in shknam.c */
  27.  
  28. STATIC_VAR long int NEARDATA followmsg;    /* last time of follow message */
  29.  
  30. STATIC_DCL void FDECL(setpaid, (struct monst *));
  31. STATIC_DCL long FDECL(addupbill, (struct monst *));
  32. STATIC_DCL void FDECL(pacify_shk, (struct monst *));
  33.  
  34. #ifdef OVLB
  35.  
  36. static void FDECL(clear_unpaid,(struct obj *));
  37. static struct bill_x *FDECL(onbill, (struct obj *, struct monst *, BOOLEAN_P));
  38. static long FDECL(check_credit, (long, struct monst *));
  39. static void FDECL(pay, (long, struct monst *));
  40. static long FDECL(get_cost, (struct obj *, struct monst *));
  41. static long FDECL(set_cost, (struct obj *, struct monst *));
  42. static const char *FDECL(shk_embellish, (struct obj *, long));
  43. static long FDECL(cost_per_charge, (struct obj *));
  44. static long FDECL(cheapest_item, (struct monst *));
  45. static int FDECL(dopayobj, (struct monst *, struct bill_x *,
  46.                 struct obj *, int, BOOLEAN_P));
  47. static long FDECL(stolen_container, (struct obj *, struct monst *, long,
  48.                      BOOLEAN_P));
  49. static long FDECL(getprice, (struct obj *));
  50. static struct obj *FDECL(bp_to_obj, (struct bill_x *));
  51. static boolean FDECL(inherits, (struct monst *, int, BOOLEAN_P));
  52. static struct monst *FDECL(next_shkp, (struct monst *, BOOLEAN_P));
  53. static boolean NDECL(angry_shk_exists);
  54. static void FDECL(rile_shk, (struct monst *));
  55. static void FDECL(remove_damage, (struct monst *, BOOLEAN_P));
  56. static void FDECL(sub_one_frombill, (struct obj *, struct monst *));
  57. static void FDECL(add_one_tobill, (struct obj *, BOOLEAN_P));
  58. static void FDECL(dropped_container, (struct obj *));
  59. static void FDECL(bill_box_content, (struct obj *, BOOLEAN_P, BOOLEAN_P,
  60.                      struct monst *));
  61.  
  62. /*
  63.     invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
  64.         obj->quan <= bp->bquan
  65.  */
  66.  
  67. static struct monst *
  68. next_shkp(shkp, withbill)
  69. register struct monst *shkp;
  70. register boolean withbill;
  71. {
  72.     for (; shkp; shkp = shkp->nmon)
  73.         if (shkp->isshk)
  74.         if (ESHK(shkp)->billct || !withbill) break;
  75.  
  76.     if (shkp) {
  77.         if (NOTANGRY(shkp)) {
  78.         if (ESHK(shkp)->surcharge) pacify_shk(shkp);
  79.         } else {
  80.         if (!ESHK(shkp)->surcharge) rile_shk(shkp);
  81.         }
  82.     }
  83.     return(shkp);
  84. }
  85.  
  86. char *
  87. shkname(mtmp)                /* called in do_name.c */
  88. register struct monst *mtmp;
  89. {
  90.     return(ESHK(mtmp)->shknam);
  91. }
  92.  
  93. void
  94. shkgone(mtmp)                /* called in mon.c */
  95. register struct monst *mtmp;
  96. {
  97.     register struct eshk *eshk = ESHK(mtmp);
  98.  
  99.     if(on_level(&(eshk->shoplevel), &u.uz)) {
  100.         remove_damage(mtmp, TRUE);
  101.         rooms[eshk->shoproom - ROOMOFFSET].resident
  102.                           = (struct monst *)0;
  103.         if(!search_special(ANY_SHOP))
  104.             level.flags.has_shop = 0;
  105.     }
  106.     /* make sure bill is set only when the
  107.      * dead shk is the resident shk.    */
  108.     if(*u.ushops == eshk->shoproom) {
  109.         setpaid(mtmp);
  110.         /* dump core when referenced */
  111.         ESHK(mtmp)->bill_p = (struct bill_x *) -1000;
  112.         u.ushops[0] = '\0';
  113.     }
  114. }
  115.  
  116. void
  117. set_residency(shkp, zero_out)
  118. register struct monst *shkp;
  119. register boolean zero_out;
  120. {
  121.     if (on_level(&(ESHK(shkp)->shoplevel), &u.uz))
  122.         rooms[ESHK(shkp)->shoproom - ROOMOFFSET].resident =
  123.         (zero_out)? (struct monst *)0 : shkp;
  124. }
  125.  
  126. void
  127. replshk(mtmp,mtmp2)
  128. register struct monst *mtmp, *mtmp2;
  129. {
  130.     if(inhishop(mtmp) && *u.ushops == ESHK(mtmp)->shoproom) {
  131.         ESHK(mtmp2)->bill_p = &(ESHK(mtmp2)->bill[0]);
  132.     }
  133. }
  134.  
  135. /* do shopkeeper specific structure munging -dlc */
  136. void
  137. restshk(mtmp)
  138. register struct monst *mtmp;
  139. {
  140.     if(ESHK(mtmp)->bill_p != (struct bill_x *) -1000)
  141.     ESHK(mtmp)->bill_p = &(ESHK(mtmp)->bill[0]);
  142. }
  143.  
  144. /* Clear the unpaid bit on all of the objects in the list. */
  145. static void
  146. clear_unpaid(list)
  147. register struct obj *list;
  148. {
  149.     while (list) {
  150.     if (Is_container(list)) clear_unpaid(list->cobj);
  151.     list->unpaid = 0;
  152.     list = list->nobj;
  153.     }
  154. }
  155.  
  156. STATIC_OVL void
  157. setpaid(shkp)    /* either you paid or left the shop or the shopkeeper died */
  158. register struct monst *shkp;
  159. {
  160.     register struct obj *obj;
  161.     register struct monst *mtmp;
  162.  
  163.     clear_unpaid(invent);
  164.     clear_unpaid(fobj);
  165.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  166.         clear_unpaid(mtmp->minvent);
  167.     for(mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon)
  168.         clear_unpaid(mtmp->minvent);
  169.  
  170.     while ((obj = billobjs) != 0) {
  171.         billobjs = obj->nobj;
  172.         dealloc_obj(obj);
  173.     }
  174.     if(shkp) {
  175.         ESHK(shkp)->billct = 0;
  176.         ESHK(shkp)->credit = 0L;
  177.         ESHK(shkp)->debit = 0L;
  178.         ESHK(shkp)->loan = 0L;
  179.     }
  180. }
  181.  
  182. STATIC_OVL long
  183. addupbill(shkp)
  184. register struct monst *shkp;
  185. {
  186.     register int ct = ESHK(shkp)->billct;
  187.     register struct bill_x *bp = ESHK(shkp)->bill_p;
  188.     register long total = 0L;
  189.  
  190.     while(ct--){
  191.         total += bp->price * bp->bquan;
  192.         bp++;
  193.     }
  194.     return(total);
  195. }
  196.  
  197. #endif /* OVLB */
  198. #ifdef OVL1
  199.  
  200. #ifdef KOPS
  201. STATIC_OVL void
  202. call_kops(shkp, nearshop)
  203. register struct monst *shkp;
  204. register boolean nearshop;
  205. {
  206.     /* Keystone Kops srt@ucla */
  207.     register boolean nokops;
  208.  
  209.     if(!shkp) return;
  210.  
  211.     if (flags.soundok)
  212.         pline("An alarm sounds!");
  213.  
  214.     nokops = ((mons[PM_KEYSTONE_KOP].geno & (G_GENOD | G_EXTINCT)) &&
  215.           (mons[PM_KOP_SERGEANT].geno & (G_GENOD | G_EXTINCT)) &&
  216.           (mons[PM_KOP_LIEUTENANT].geno & (G_GENOD | G_EXTINCT)) &&
  217.           (mons[PM_KOP_KAPTAIN].geno & (G_GENOD | G_EXTINCT)));
  218.  
  219.     if(!angry_guards(!flags.soundok) && nokops) {
  220.         if(flags.verbose && flags.soundok)
  221.         pline("But no one seems to respond to it.");
  222.         return;
  223.     }
  224.  
  225.     if(nokops) return;
  226.  
  227.     {
  228.         coord mm;
  229.  
  230.         if (nearshop) {
  231.         /* Create swarm around you, if you merely "stepped out" */
  232.         if (flags.verbose)
  233.             pline("The Keystone Kops appear!");
  234.         mm.x = u.ux;
  235.         mm.y = u.uy;
  236.         makekops(&mm);
  237.         return;
  238.         }
  239.         if (flags.verbose)
  240.          pline("The Keystone Kops are after you!");
  241.         /* Create swarm near down staircase (hinders return to level) */
  242.         mm.x = xdnstair;
  243.         mm.y = ydnstair;
  244.         makekops(&mm);
  245.         /* Create swarm near shopkeeper (hinders return to shop) */
  246.         mm.x = shkp->mx;
  247.         mm.y = shkp->my;
  248.         makekops(&mm);
  249.     }
  250. }
  251. #endif    /* KOPS */
  252.  
  253. /* x,y is strictly inside shop */
  254. char
  255. inside_shop(x, y)
  256. register xchar x, y;
  257. {
  258.     register char rno;
  259.  
  260.     rno = levl[x][y].roomno;
  261.     if ((rno < ROOMOFFSET) || levl[x][y].edge || !IS_SHOP(rno-ROOMOFFSET))
  262.         return(NO_ROOM);
  263.     else
  264.         return(rno);
  265. }
  266.  
  267. void
  268. u_left_shop(leavestring, newlev)
  269. register char *leavestring;
  270. register boolean newlev;
  271. {
  272.     register struct monst *shkp;
  273.     register struct eshk *eshkp;
  274.     register long total;
  275.  
  276.     /*
  277.      * IF player
  278.      * ((didn't leave outright) AND
  279.      *  ((he is now strictly-inside the shop) OR
  280.      *   (he wasn't strictly-inside last turn anyway)))
  281.      * THEN (there's nothing to do, so just return)
  282.      */
  283.     if(!*leavestring &&
  284.        (!levl[u.ux][u.uy].edge || levl[u.ux0][u.uy0].edge))
  285.         return;
  286.  
  287.     shkp = shop_keeper(*u.ushops0);
  288.  
  289.     if(!shkp || !inhishop(shkp))
  290.                 /* shk died, teleported, changed levels... */
  291.         return;
  292.  
  293.     eshkp = ESHK(shkp);
  294.  
  295.     if(!eshkp->billct && !eshkp->debit)    /* bill is settled */
  296.         return;
  297.  
  298.     if(!*leavestring) {
  299.         /*
  300.          * Player just stepped onto shop-boundary (known from above logic).
  301.          * Try to intimidate him into paying his bill
  302.          */
  303.  
  304.         verbalize(NOTANGRY(shkp) ?
  305.               "%s!  Please pay before leaving." :
  306.               "%s!  Don't you leave without paying!",
  307.               plname);
  308.         return;
  309.     }
  310.         /* by this point, we know an actual robbery has taken place */
  311.     You("escaped the shop without paying!");
  312.     total = (addupbill(shkp) + eshkp->debit);
  313.     eshkp->robbed += total;
  314.     eshkp->credit = 0L;
  315.     eshkp->debit = 0L;
  316.     setpaid(shkp);
  317.     You("stole %ld zorkmid%s worth of merchandise.",
  318.         total, plur(total));
  319.     if (pl_character[0] != 'R') /* stealing is unlawful */
  320.         adjalign(-sgn(u.ualign.type));
  321.  
  322.     hot_pursuit(shkp);
  323. #ifdef KOPS
  324.     call_kops(shkp, (!newlev && levl[u.ux0][u.uy0].edge));
  325. #else
  326.     (void) angry_guards(FALSE);
  327. #endif
  328. }
  329.  
  330. void
  331. u_entered_shop(enterstring)
  332. register char *enterstring;
  333. {
  334.  
  335.     register int rt;
  336.     register struct monst *shkp;
  337.     register struct eshk *eshkp;
  338.     static const char no_shk[] = "This shop appears to be deserted.";
  339.     static char empty_shops[5];
  340.  
  341.     if(!*enterstring)
  342.         return;
  343.  
  344.     if(!(shkp = shop_keeper(*enterstring))) {
  345.         if (!index(empty_shops, *enterstring) &&
  346.         in_rooms(u.ux, u.uy, SHOPBASE) !=
  347.                   in_rooms(u.ux0, u.uy0, SHOPBASE))
  348.         pline(no_shk);
  349.         Strcpy(empty_shops, u.ushops);
  350.         u.ushops[0] = '\0';
  351.         return;
  352.     }
  353.  
  354.     eshkp = ESHK(shkp);
  355.  
  356.     if (!inhishop(shkp)) {
  357.         /* dump core when referenced */
  358.         eshkp->bill_p = (struct bill_x *) -1000;
  359.         if (!index(empty_shops, *enterstring))
  360.         pline(no_shk);
  361.         Strcpy(empty_shops, u.ushops);
  362.         u.ushops[0] = '\0';
  363.         return;
  364.     }
  365.  
  366.     eshkp->bill_p = &(eshkp->bill[0]);
  367.  
  368.     if (!eshkp->visitct || strncmpi(eshkp->customer, plname, PL_NSIZ)) {
  369.         /* You seem to be new here */
  370.         eshkp->visitct = 0;
  371.         eshkp->following = 0;
  372.         (void) strncpy(eshkp->customer,plname,PL_NSIZ);
  373.         pacify_shk(shkp);
  374.     }
  375.  
  376.     if (eshkp->following)
  377.         return;
  378.  
  379.     if (Invis) {
  380.         pline("%s senses your presence.", shkname(shkp));
  381.         verbalize("Invisible customers are not welcome!");
  382.         return;
  383.     }
  384.  
  385.     rt = rooms[*enterstring - ROOMOFFSET].rtype;
  386.  
  387.     if (ANGRY(shkp)) {
  388.         verbalize("So, %s, you dare return to %s %s?!",
  389.               plname,
  390.               s_suffix(shkname(shkp)),
  391.               shtypes[rt - SHOPBASE].name);
  392.     } else if (eshkp->robbed) {
  393.         verbalize("Beware, %s!  I am upset about missing stock!",
  394.               plname);
  395.     } else {
  396.         verbalize("Hello, %s!  Welcome%s to %s %s!",
  397.               plname,
  398.               eshkp->visitct++ ? " again" : "",
  399.               s_suffix(shkname(shkp)),
  400.               shtypes[rt - SHOPBASE].name);
  401.     }
  402.     if(carrying(PICK_AXE) != (struct obj *)0 &&
  403.                  /* can't do anything if teleported in */
  404.                  !inside_shop(u.ux, u.uy)) {
  405.         verbalize(NOTANGRY(shkp) ?
  406.               "Will you please leave your pick-axe outside?" :
  407.               "Leave the pick-axe outside.");
  408.         (void) dochug(shkp);
  409.     }
  410.     return;
  411. }
  412.  
  413. #endif /* OVL1 */
  414. #ifdef OVLB
  415.  
  416. int
  417. inhishop(mtmp)
  418. register struct monst *mtmp;
  419. {
  420.     return(index(in_rooms(mtmp->mx, mtmp->my, SHOPBASE),
  421.              ESHK(mtmp)->shoproom) &&
  422.         on_level(&(ESHK(mtmp)->shoplevel), &u.uz));
  423. }
  424.  
  425. struct monst *
  426. shop_keeper(rmno)
  427. register char rmno;
  428. {
  429.     struct monst *shkp = rmno >= ROOMOFFSET ?
  430.                 rooms[rmno - ROOMOFFSET].resident : 0;
  431.  
  432.     if (shkp) {
  433.         if (NOTANGRY(shkp)) {
  434.         if (ESHK(shkp)->surcharge) pacify_shk(shkp);
  435.         } else {
  436.         if (!ESHK(shkp)->surcharge) rile_shk(shkp);
  437.         }
  438.     }
  439.     return shkp;
  440. }
  441.  
  442. #ifdef SOUNDS
  443. boolean
  444. tended_shop(sroom)
  445. register struct mkroom *sroom;
  446. {
  447.     register struct monst *mtmp = sroom->resident;
  448.  
  449.     if (!mtmp)
  450.         return(FALSE);
  451.     else
  452.         return(inhishop(mtmp));
  453. }
  454. #endif    /* SOUNDS */
  455.  
  456. static struct bill_x *
  457. onbill(obj, shkp, silent)
  458. register struct obj *obj;
  459. register struct monst *shkp;
  460. register boolean silent;
  461. {
  462.     if (shkp) {
  463.         register struct bill_x *bp = ESHK(shkp)->bill_p;
  464.         register int ct = ESHK(shkp)->billct;
  465.  
  466.         while (--ct >= 0)
  467.             if (bp->bo_id == obj->o_id) {
  468.             if (!obj->unpaid) pline("onbill: paid obj on bill?");
  469.             return bp;
  470.             } else bp++;
  471.     }
  472.     if(obj->unpaid & !silent) pline("onbill: unpaid obj not on bill?");
  473.     return (struct bill_x *)0;
  474. }
  475.  
  476. /* Delete the contents of the given object. */
  477. void
  478. delete_contents(obj)
  479. register struct obj *obj;
  480. {
  481.     register struct obj *curr, *next;
  482.  
  483.     for (curr = obj->cobj; curr; curr = next) {
  484.         next = curr->nobj;
  485.         obfree(curr, (struct obj *)0);
  486.     }
  487.     obj->cobj = (struct obj *) 0;
  488. }
  489.  
  490. /* called with two args on merge */
  491. void
  492. obfree(obj, merge)
  493. register struct obj *obj, *merge;
  494. {
  495.     register struct bill_x *bp;
  496.     register struct bill_x *bpm;
  497.     register struct monst *shkp;
  498.  
  499.     if(obj->oclass == FOOD_CLASS) food_disappears(obj);
  500.  
  501.     if (obj->cobj) delete_contents(obj);
  502.  
  503.     shkp = shop_keeper(*u.ushops);
  504.  
  505.     if ((bp = onbill(obj, shkp, FALSE)) != 0) {
  506.         if(!merge){
  507.             bp->useup = 1;
  508.             obj->unpaid = 0;    /* only for doinvbill */
  509.             obj->nobj = billobjs;
  510.             billobjs = obj;
  511.             return;
  512.         }
  513.         bpm = onbill(merge, shkp, FALSE);
  514.         if(!bpm){
  515.             /* this used to be a rename */
  516.             impossible("obfree: not on bill??");
  517.             return;
  518.         } else {
  519.             /* this was a merger */
  520.             bpm->bquan += bp->bquan;
  521.             ESHK(shkp)->billct--;
  522. #ifdef DUMB
  523.             {
  524.             /* DRS/NS 2.2.6 messes up -- Peter Kendell */
  525.                 int indx = ESHK(shkp)->billct;
  526.                 *bp = ESHK(shkp)->bill_p[indx];
  527.             }
  528. #else
  529.             *bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
  530. #endif
  531.         }
  532.     }
  533.     dealloc_obj(obj);
  534. }
  535.  
  536. static long
  537. check_credit(tmp, shkp)
  538. long tmp;
  539. register struct monst *shkp;
  540. {
  541.     long credit = ESHK(shkp)->credit;
  542.  
  543.     if(credit == 0L) return(tmp);
  544.     if(credit >= tmp) {
  545.         pline("The price is deducted from your credit.");
  546.         ESHK(shkp)->credit -=tmp;
  547.         tmp = 0L;
  548.     } else {
  549.         pline("The price is partially covered by your credit.");
  550.         ESHK(shkp)->credit = 0L;
  551.         tmp -= credit;
  552.     }
  553.     return(tmp);
  554. }
  555.  
  556. static void
  557. pay(tmp,shkp)
  558. long tmp;
  559. register struct monst *shkp;
  560. {
  561.     long robbed = ESHK(shkp)->robbed;
  562.     long balance = ((tmp <= 0L) ? tmp : check_credit(tmp, shkp));
  563.  
  564.     u.ugold -= balance;
  565.     shkp->mgold += balance;
  566.     flags.botl = 1;
  567.     if(robbed) {
  568.         robbed -= tmp;
  569.         if(robbed < 0) robbed = 0L;
  570.         ESHK(shkp)->robbed = robbed;
  571.     }
  572. }
  573.  
  574. /* return shkp to home position */
  575. void
  576. home_shk(shkp, killkops)
  577. register struct monst *shkp;
  578. register boolean killkops;
  579. {
  580.     register xchar x = ESHK(shkp)->shk.x, y = ESHK(shkp)->shk.y;
  581.  
  582.     (void) mnearto(shkp, x, y, TRUE);
  583.     level.flags.has_shop = 1;
  584.     if (killkops) {
  585. #ifdef KOPS
  586.         kops_gone(TRUE);
  587. #else
  588.         You("feel vaguely apprehensive.");
  589. #endif
  590.         pacify_guards();
  591.     }
  592. }
  593.  
  594. static boolean
  595. angry_shk_exists()
  596. {
  597.     register struct monst *shkp;
  598.  
  599.     for (shkp = next_shkp(fmon, FALSE);
  600.         shkp; shkp = next_shkp(shkp->nmon, FALSE))
  601.         if (ANGRY(shkp)) return(TRUE);
  602.     return(FALSE);
  603. }
  604.  
  605. /* remove previously applied surcharge from all billed items */
  606. STATIC_OVL void
  607. pacify_shk(shkp)
  608. register struct monst *shkp;
  609. {
  610.     NOTANGRY(shkp) = TRUE;    /* make peaceful */
  611.     if (ESHK(shkp)->surcharge) {
  612.         register struct bill_x *bp = ESHK(shkp)->bill_p;
  613.         register int ct = ESHK(shkp)->billct;
  614.  
  615.         ESHK(shkp)->surcharge = FALSE;
  616.         while (ct-- > 0) {
  617.             register long reduction = (bp->price + 3L) / 4L;
  618.             bp->price -= reduction;        /* undo 33% increase */
  619.             bp++;
  620.         }
  621.     }
  622. }
  623.  
  624. /* add aggravation surcharge to all billed items */
  625. static void
  626. rile_shk(shkp)
  627. register struct monst *shkp;
  628. {
  629.     NOTANGRY(shkp) = FALSE;    /* make angry */
  630.     if (!ESHK(shkp)->surcharge) {
  631.         register struct bill_x *bp = ESHK(shkp)->bill_p;
  632.         register int ct = ESHK(shkp)->billct;
  633.  
  634.         ESHK(shkp)->surcharge = TRUE;
  635.         while (ct-- > 0) {
  636.             register long surcharge = (bp->price + 2L) / 3L;
  637.             bp->price += surcharge;
  638.             bp++;
  639.         }
  640.     }
  641. }
  642.  
  643. void
  644. make_happy_shk(shkp, silentkops)
  645. register struct monst *shkp;
  646. register boolean silentkops;
  647. {
  648.     register boolean wasmad = ANGRY(shkp);
  649.  
  650.     pacify_shk(shkp);
  651.     ESHK(shkp)->following = 0;
  652.     ESHK(shkp)->robbed = 0L;
  653.     if (pl_character[0] != 'R')
  654.         adjalign(sgn(u.ualign.type));
  655.     if(!inhishop(shkp)) {
  656.         pline("Satisfied, %s suddenly disappears!", mon_nam(shkp));
  657.         if(on_level(&(ESHK(shkp)->shoplevel), &u.uz))
  658.             home_shk(shkp, FALSE);
  659.         else
  660.             migrate_to_level(shkp,
  661.                  ledger_no(&(ESHK(shkp)->shoplevel)), 0);
  662.     } else if(wasmad)
  663.         pline("%s calms down.", Monnam(shkp));
  664.  
  665.     if(!angry_shk_exists()) {
  666. #ifdef KOPS
  667.         kops_gone(silentkops);
  668. #endif
  669.         pacify_guards();
  670.     }
  671. }
  672.  
  673. void
  674. hot_pursuit(shkp)
  675. register struct monst *shkp;
  676. {
  677.     if(!shkp->isshk) return;
  678.  
  679.     rile_shk(shkp);
  680.     ESHK(shkp)->following = 1;
  681. }
  682.  
  683. /* used when the shkp is teleported out of his shop,
  684.  * or when the player is not on a costly_spot and he
  685.  * damages something inside the shop.  these conditions
  686.  * must be checked by the calling function.
  687.  */
  688. void
  689. make_angry_shk(shkp, ox, oy)
  690. register struct monst *shkp;
  691. register xchar ox,oy;
  692. {
  693.     if(index(in_rooms(ox, oy, SHOPBASE), ESHK(shkp)->shoproom) &&
  694.         !ANGRY(shkp)) {
  695.         ESHK(shkp)->robbed += (addupbill(shkp) +
  696.                        ESHK(shkp)->debit + ESHK(shkp)->loan);
  697.         ESHK(shkp)->robbed -= ESHK(shkp)->credit;
  698.         if(ESHK(shkp)->robbed < 0L)
  699.             ESHK(shkp)->robbed = 0L;
  700.         ESHK(shkp)->credit = 0L;
  701.         setpaid(shkp);
  702.     }
  703.     if(!ANGRY(shkp)) pline("%s gets angry!", Monnam(shkp));
  704.     else pline("%s is furious!", Monnam(shkp));
  705.     hot_pursuit(shkp);
  706. }
  707.  
  708. static const char no_money[] = "Moreover, you%s have no money.";
  709.  
  710. static long
  711. cheapest_item(shkp)   /* delivers the cheapest item on the list */
  712. register struct monst *shkp;
  713. {
  714.     register int ct = ESHK(shkp)->billct;
  715.     register struct bill_x *bp = ESHK(shkp)->bill_p;
  716.     register long gmin = (bp->price * bp->bquan);
  717.  
  718.     while(ct--){
  719.         if(bp->price * bp->bquan < gmin)
  720.             gmin = bp->price * bp->bquan;
  721.         bp++;
  722.     }
  723.     return(gmin);
  724. }
  725.  
  726. int
  727. dopay()
  728. {
  729.     long ltmp;
  730.     register struct monst *nxtm = (struct monst *)0;
  731.     register struct monst *shkp, *resident = (struct monst *)0;
  732.     register struct eshk *eshkp;
  733.     int pass, tmp, sk = 0, seensk = 0;
  734.     register boolean paid = FALSE, stashed_gold = (hidden_gold() > 0L);
  735.  
  736.     multi = 0;
  737.  
  738.     /* find how many shk's there are, how many are in */
  739.     /* sight, and are you in a shop room with one.    */
  740.     for (shkp = next_shkp(fmon, FALSE);
  741.         shkp; shkp = next_shkp(shkp->nmon, FALSE)) {
  742.         sk++;
  743.         if (ANGRY(shkp) && distu(shkp->mx, shkp->my) <= 2) nxtm = shkp;
  744.         if (canseemon(shkp) || sensemon(shkp)) seensk++;
  745.         if (inhishop(shkp) && (*u.ushops == ESHK(shkp)->shoproom))
  746.         resident = shkp;
  747.     }
  748.  
  749.     if (nxtm) {            /* Player should always appease an */
  750.          shkp = nxtm;        /* irate shk standing next to them. */
  751.          goto proceed;
  752.     }
  753.  
  754.     if ((!sk && (!Blind || Telepat)) || (!Blind && !seensk)) {
  755.       pline("There appears to be no shopkeeper here to receive your payment.");
  756.         return(0);
  757.     }
  758.  
  759.     if(!seensk) {
  760.         You("can't see...");
  761.         return(0);
  762.     }
  763.  
  764.     /* the usual case.  allow paying at a distance when */
  765.     /* inside a tended shop.  should we change that?    */
  766.     if(sk == 1 && resident) {
  767.         shkp = resident;
  768.         goto proceed;
  769.     }
  770.  
  771.     if (seensk == 1) {
  772.         for (shkp = next_shkp(fmon, FALSE);
  773.             shkp; shkp = next_shkp(shkp->nmon, FALSE))
  774.             if (canseemon(shkp) || sensemon(shkp)) break;
  775.         if (shkp != resident && distu(shkp->mx, shkp->my) > 2) {
  776.             pline("%s is not near enough to receive your payment.",
  777.                          Monnam(shkp));
  778.             return(0);
  779.         }
  780.     } else {
  781.         struct monst *mtmp;
  782.         coord cc;
  783.         int cx, cy;
  784.  
  785.         pline("Pay whom?");
  786.         cc.x = u.ux;
  787.         cc.y = u.uy;
  788.         getpos(&cc, TRUE, "the creature you want to pay");
  789.         cx = cc.x;
  790.         cy = cc.y;
  791.         if(cx == -10) return(0); /* player pressed esc */
  792.         if(cx < 0) {
  793.              pline("Try again...");
  794.              return(0);
  795.         }
  796.         if(u.ux == cx && u.uy == cy) {
  797.              You("are generous to yourself.");
  798.              return(0);
  799.         }
  800.         mtmp = m_at(cx, cy);
  801.         if(!mtmp) {
  802.              pline("There is no one there to receive your payment.");
  803.              return(0);
  804.         }
  805.         if(!mtmp->isshk) {
  806.              pline("%s is not interested in your payment.",
  807.                     Monnam(mtmp));
  808.              return(0);
  809.         }
  810.         if (mtmp != resident && distu(mtmp->mx, mtmp->my) > 2) {
  811.              pline("%s is too far to receive your payment.",
  812.                     Monnam(mtmp));
  813.              return(0);
  814.         }
  815.         shkp = mtmp;
  816.     }
  817.  
  818.     if(!shkp) {
  819. #ifdef DEBUG
  820.         pline("dopay: null shkp.");
  821. #endif
  822.         return(0);
  823.     }
  824. proceed:
  825.     eshkp = ESHK(shkp);
  826.  
  827.     ltmp = eshkp->robbed;
  828.     if(shkp != resident && NOTANGRY(shkp)) {
  829.         if(!ltmp)
  830.             You("do not owe %s anything.", mon_nam(shkp));
  831.         else if(!u.ugold) {
  832.             You("%shave no money.", stashed_gold ? "seem to " : "");
  833.             if(stashed_gold)
  834.             pline("But you have some gold stashed away.");
  835.         } else {
  836.             const char *pronoun = shkp->female ? "she" : "he";
  837.             long ugold = u.ugold;
  838.  
  839.             if(ugold > ltmp) {
  840.             You("give %s the %ld gold piece%s %s asked for.",
  841.                 mon_nam(shkp), ltmp, plur(ltmp), pronoun);
  842.             pay(ltmp, shkp);
  843.             } else {
  844.             You("give %s all your%s gold.", mon_nam(shkp),
  845.                     stashed_gold ? " openly kept" : "");
  846.             pay(u.ugold, shkp);
  847.             if (stashed_gold) pline("But you have hidden gold!");
  848.             }
  849.             if((ugold < ltmp/2L) || (ugold < ltmp && stashed_gold))
  850.             pline("Unfortunately, %s doesn't look satisfied.",
  851.                 pronoun);
  852.             else
  853.             make_happy_shk(shkp, FALSE);
  854.         }
  855.         return(1);
  856.     }
  857.  
  858.     /* ltmp is still eshkp->robbed here */
  859.     if (!eshkp->billct && !eshkp->debit) {
  860.         const char *pronoun = shkp->female ? "her" : "him";
  861.         const char *possessive = shkp->female ? "her" : "his";
  862.  
  863.         if(!ltmp && NOTANGRY(shkp)) {
  864.             You("do not owe %s anything.", mon_nam(shkp));
  865.             if(!u.ugold) pline(no_money, stashed_gold ?
  866.                        " seem to" : "");
  867.         } else if(ltmp) {
  868.             pline("%s is after blood, not money!", Monnam(shkp));
  869.             if(u.ugold < ltmp/2L ||
  870.                 (u.ugold < ltmp && stashed_gold)) {
  871.             if(!u.ugold) pline(no_money, stashed_gold ?
  872.                                " seem to" : "");
  873.             else pline("Besides, you don't have enough to interest %s.",
  874.                 pronoun);
  875.             return(1);
  876.             }
  877.             pline("But since %s shop has been robbed recently,",
  878.             possessive);
  879.             pline("you %scompensate %s for %s losses.",
  880.             (u.ugold < ltmp) ? "partially " : "",
  881.             mon_nam(shkp), possessive);
  882.             pay(u.ugold < ltmp ? u.ugold : ltmp, shkp);
  883.             make_happy_shk(shkp, FALSE);
  884.         } else {
  885.             /* shopkeeper is angry, but has not been robbed --
  886.              * door broken, attacked, etc. */
  887.             pline("%s is after your hide, not your money!",
  888.                              mon_nam(shkp));
  889.             if(u.ugold < 1000L) {
  890.             if(!u.ugold) pline(no_money, stashed_gold ?
  891.                          " seem to" : "");
  892.             else pline("Besides, you don't have enough to interest %s.",
  893.                     pronoun);
  894.             return(1);
  895.             }
  896.             You("try to appease %s by giving %s 1000 gold pieces.",
  897.             x_monnam(shkp, 1, "angry", 0), pronoun);
  898.             pay(1000L,shkp);
  899.             if (strncmp(eshkp->customer, plname, PL_NSIZ) || rn2(3))
  900.             make_happy_shk(shkp, FALSE);
  901.             else
  902.             pline("But %s is as angry as ever.", mon_nam(shkp));
  903.         }
  904.         return(1);
  905.     }
  906.     if(shkp != resident) {
  907.         impossible("dopay: not to shopkeeper?");
  908.         if(resident) setpaid(resident);
  909.         return(0);
  910.     }
  911.     /* pay debt, if any, first */
  912.     if(eshkp->debit) {
  913.         long dtmp = eshkp->debit;
  914.         long loan = eshkp->loan;
  915.         char sbuf[BUFSZ];
  916.  
  917.         Sprintf(sbuf, "You owe %s %ld zorkmid%s ",
  918.                        shkname(shkp), dtmp, plur(dtmp));
  919.         if(loan) {
  920.             if(loan == dtmp)
  921.             Strcat(sbuf, "you picked up in the store.");
  922.             else Strcat(sbuf,
  923.                "for gold picked up and the use of merchandise.");
  924.         } else Strcat(sbuf, "for the use of merchandise.");
  925.         pline(sbuf);
  926.         if (u.ugold + eshkp->credit < dtmp) {
  927.             pline("But you don't%s have enough gold%s.",
  928.             stashed_gold ? " seem to" : "",
  929.             eshkp->credit ? " or credit" : "");
  930.             return(1);
  931.         } else {
  932.             if (eshkp->credit >= dtmp) {
  933.             eshkp->credit -= dtmp;
  934.             eshkp->debit = 0L;
  935.             eshkp->loan = 0L;
  936.             Your("debt is covered by your credit.");
  937.             } else if (!eshkp->credit) {
  938.             u.ugold -= dtmp;
  939.             shkp->mgold += dtmp;
  940.             eshkp->debit = 0L;
  941.             eshkp->loan = 0L;
  942.             You("pay that debt.");
  943.             flags.botl = 1;
  944.             } else {
  945.             dtmp -= eshkp->credit;
  946.             eshkp->credit = 0L;
  947.             u.ugold -= dtmp;
  948.             shkp->mgold += dtmp;
  949.             eshkp->debit = 0L;
  950.             eshkp->loan = 0L;
  951.             pline("That debt is partially offset by your credit.");
  952.             You("pay the remainder.");
  953.             flags.botl = 1;
  954.             }
  955.             paid = TRUE;
  956.         }
  957.     }
  958.     /* now check items on bill */
  959.     if (eshkp->billct) {
  960.         register boolean itemize;
  961.  
  962.         if (!u.ugold && !eshkp->credit) {
  963.         You("%shave no money or credit%s.",
  964.                     stashed_gold ? "seem to " : "",
  965.                     paid ? " left" : "");
  966.         return(0);
  967.         }
  968.         if ((u.ugold + eshkp->credit) < cheapest_item(shkp)) {
  969.         You("don't have enough money to buy%s the item%s you picked.",
  970.             eshkp->billct > 1 ? " any of" : "", plur(eshkp->billct));
  971.         if(stashed_gold)
  972.             pline("Maybe you have some gold stashed away?");
  973.         return(0);
  974.         }
  975.  
  976.         /* this isn't quite right; it itemizes without asking if the
  977.          * single item on the bill is partly used up and partly unpaid */
  978.         itemize = (eshkp->billct > 1 ? yn("Itemized billing?") == 'y' : 1);
  979.  
  980.         for (pass = 0; pass <= 1; pass++) {
  981.         tmp = 0;
  982.         while (tmp < eshkp->billct) {
  983.             register struct obj *otmp;
  984.             register struct bill_x *bp = &(eshkp->bill_p[tmp]);
  985.  
  986.             /* find the object on one of the lists */
  987.             if (!(otmp = bp_to_obj(bp))) {
  988.             impossible("Shopkeeper administration out of order.");
  989.             setpaid(shkp);    /* be nice to the player */
  990.             return 1;
  991.             }
  992.             if (pass == bp->useup && otmp->quan == bp->bquan) {
  993.             /* pay for used-up items on first pass and others
  994.              * on second, so player will be stuck in the store
  995.              * less often; things which are partly used up
  996.              * are processed on both passes */
  997.             tmp++;
  998.             } else {
  999.             switch (dopayobj(shkp, bp, otmp, pass, itemize)) {
  1000.               case PAY_CANT:
  1001.                 return 1;    /*break*/
  1002.               case PAY_BROKE:
  1003.                 paid = TRUE;
  1004.                 goto thanks;    /*break*/
  1005.               case PAY_SKIP:
  1006.                 tmp++;
  1007.                 continue;    /*break*/
  1008.               case PAY_SOME:
  1009.                 paid = TRUE;
  1010.                 if (itemize) bot();
  1011.                 continue;    /*break*/
  1012.               case PAY_BUY:
  1013.                 paid = TRUE;
  1014.                 break;
  1015.             }
  1016.             if (itemize) bot();
  1017.             *bp = eshkp->bill_p[--eshkp->billct];
  1018.             }
  1019.         }
  1020.         }
  1021.     }
  1022. thanks:
  1023.     if(!ANGRY(shkp) && paid)
  1024.         verbalize("Thank you for shopping in %s %s!",
  1025.         s_suffix(shkname(shkp)),
  1026.         shtypes[rooms[eshkp->shoproom - ROOMOFFSET].rtype - SHOPBASE].name);
  1027.     return(1);
  1028. }
  1029.  
  1030. /* return 2 if used-up portion paid */
  1031. /*      1 if paid successfully    */
  1032. /*      0 if not enough money     */
  1033. /*     -1 if skip this object     */
  1034. /*     -2 if no money/credit left */
  1035. static int
  1036. dopayobj(shkp, bp, obj, which, itemize)
  1037. register struct monst *shkp;
  1038. register struct bill_x *bp;
  1039. register struct obj *obj;
  1040. int    which;        /* 0 => used-up item, 1 => other (unpaid or lost) */
  1041. boolean itemize;
  1042. {
  1043.     long ltmp, quan, save_quan;
  1044.     int buy;
  1045.     boolean stashed_gold = (hidden_gold() > 0L),
  1046.         consumed = (which == 0);
  1047.  
  1048.     if(!obj->unpaid && !bp->useup){
  1049.         impossible("Paid object on bill??");
  1050.         return PAY_BUY;
  1051.     }
  1052.     if(itemize && u.ugold + ESHK(shkp)->credit == 0L){
  1053.         You("%shave no money or credit left.",
  1054.                  stashed_gold ? "seem to " : "");
  1055.         return PAY_BROKE;
  1056.     }
  1057.     /* we may need to temporarily adjust the object, if part of the
  1058.        original quantity has been used up but part remains unpaid  */
  1059.     save_quan = obj->quan;
  1060.     if (consumed) {
  1061.         /* either completely used up (simple), or split needed */
  1062.         quan = bp->bquan;
  1063.         if (quan > obj->quan)    /* difference is amount used up */
  1064.         quan -= obj->quan;
  1065.     } else {
  1066.         /* dealing with ordinary unpaid item */
  1067.         quan = obj->quan;
  1068.     }
  1069.     obj->quan = quan;    /* to be used by doname() */
  1070.     obj->unpaid = 0;    /* ditto */
  1071.     ltmp = bp->price * quan;
  1072.     buy = PAY_BUY;        /* flag; if changed then return early */
  1073.  
  1074.     if (itemize) {
  1075.         char qbuf[BUFSZ];
  1076.         Sprintf(qbuf,"%s for %ld zorkmid%s.  Pay?", quan == 1L ?
  1077.             Doname2(obj) : doname(obj), ltmp, plur(ltmp));
  1078.         if (yn(qbuf) == 'n') {
  1079.         buy = PAY_SKIP;        /* don't want to buy */
  1080.         } else if (quan < bp->bquan && !consumed) { /* partly used goods */
  1081.         obj->quan = bp->bquan - save_quan;    /* used up amount */
  1082.         verbalize("%s for the other %s before buying %s.",
  1083.               ANGRY(shkp) ? "Pay" : "Please pay", xname(obj),
  1084.               save_quan > 1L ? "these" : "this one");
  1085.         buy = PAY_SKIP;        /* shk won't sell */
  1086.         }
  1087.     }
  1088.     if (buy == PAY_BUY && u.ugold + ESHK(shkp)->credit < ltmp) {
  1089.         You("don't%s have gold%s enough to pay for %s.",
  1090.         stashed_gold ? " seem to" : "",
  1091.         (ESHK(shkp)->credit > 0L) ? " or credit" : "",
  1092.         doname(obj));
  1093.         buy = itemize ? PAY_SKIP : PAY_CANT;
  1094.     }
  1095.  
  1096.     if (buy != PAY_BUY) {
  1097.         /* restore unpaid object to original state */
  1098.         obj->quan = save_quan;
  1099.         obj->unpaid = 1;
  1100.         return buy;
  1101.     }
  1102.  
  1103.     pay(ltmp, shkp);
  1104.     You("bought %s for %ld gold piece%s.",
  1105.         doname(obj), ltmp, plur(ltmp));
  1106.     obj->quan = save_quan;        /* restore original count */
  1107.     /* quan => amount just bought, save_quan => remaining unpaid count */
  1108.     if (consumed) {
  1109.         if (quan != save_quan) {
  1110.         /* eliminate used-up portion; remainder is still unpaid */
  1111.         bp->bquan = obj->quan;
  1112.         obj->unpaid = 1;
  1113.         bp->useup = 0;
  1114.         } else {    /* completely used-up, so get rid of it */
  1115.         register struct obj *otmp = billobjs;
  1116.         if(obj == billobjs)
  1117.             billobjs = obj->nobj;
  1118.         else {
  1119.             while(otmp && otmp->nobj != obj) otmp = otmp->nobj;
  1120.             if(otmp) otmp->nobj = obj->nobj;
  1121.             else impossible("Error in shopkeeper administration.");
  1122.         }
  1123.         dealloc_obj(obj);
  1124.         }
  1125.     }
  1126.     return quan != save_quan ? PAY_SOME : PAY_BUY;
  1127. }
  1128.  
  1129. /* routine called after dying (or quitting) */
  1130. boolean
  1131. paybill(croaked)
  1132. register boolean croaked;
  1133. {
  1134.     register struct monst *mtmp, *mtmp2, *resident= (struct monst *)0;
  1135.     register boolean taken = FALSE;
  1136.     register int numsk = 0;
  1137.  
  1138.     /* give shopkeeper first crack */
  1139.     if ((mtmp = shop_keeper(*u.ushops)) && inhishop(mtmp)) {
  1140.         numsk++;
  1141.         resident = mtmp;
  1142.         taken = inherits(resident, numsk, croaked);
  1143.     }
  1144.     for (mtmp = next_shkp(fmon, FALSE);
  1145.         mtmp; mtmp = next_shkp(mtmp2, FALSE)) {
  1146.         mtmp2 = mtmp->nmon;
  1147.         if (mtmp != resident) {
  1148.         /* for bones: we don't want a shopless shk around */
  1149.         if(!on_level(&(ESHK(mtmp)->shoplevel), &u.uz))
  1150.             mongone(mtmp);
  1151.         else {
  1152.             numsk++;
  1153.             taken |= inherits(mtmp, numsk, croaked);
  1154.         }
  1155.         }
  1156.     }
  1157.     if(numsk == 0) return(FALSE);
  1158.     return(taken);
  1159. }
  1160.  
  1161. static boolean
  1162. inherits(shkp, numsk, croaked)
  1163. register struct monst *shkp;
  1164. register int numsk;
  1165. register boolean croaked;
  1166. {
  1167.     register long loss = 0L;
  1168.     register struct obj *otmp;
  1169.     register struct eshk *eshkp = ESHK(shkp);
  1170.     register xchar ox, oy;
  1171.     register boolean take = FALSE, taken = FALSE;
  1172.     register int roomno = *u.ushops;
  1173.  
  1174.     /* the simplifying principle is that first-come */
  1175.     /* already took everything you had.        */
  1176.     if(numsk > 1) {
  1177.         if(cansee(shkp->mx, shkp->my) && croaked)
  1178.         pline("%s %slooks at your corpse%s%s", Monnam(shkp),
  1179.              (shkp->msleep || shkp->mfrozen) ?
  1180.                    "wakes up, " : "",
  1181.              !rn2(2) ? (shkp->female ? ", shakes her head," :
  1182.                  ", shakes his head,") : "",
  1183.              !inhishop(shkp) ? " and disappears. " : " and sighs.");
  1184.         taken = (roomno == eshkp->shoproom);
  1185.         goto skip;
  1186.     }
  1187.  
  1188.     /* get one case out of the way: you die in the shop, the */
  1189.     /* shopkeeper is peaceful, nothing stolen, nothing owed. */
  1190.     if(roomno == eshkp->shoproom && inhishop(shkp) &&
  1191.         !IS_DOOR(levl[u.ux][u.uy].typ) && !eshkp->billct &&
  1192.         !eshkp->robbed && !eshkp->debit &&
  1193.          NOTANGRY(shkp) && !eshkp->following) {
  1194.         if (invent)
  1195.             pline("%s gratefully inherits all your possessions.",
  1196.                 shkname(shkp));
  1197.         goto clear;
  1198.     }
  1199.  
  1200.     if (eshkp->billct || eshkp->debit || eshkp->robbed) {
  1201.         register long total = 0L;
  1202.  
  1203.         if(roomno == eshkp->shoproom && inhishop(shkp))
  1204.             total = (addupbill(shkp) + eshkp->debit);
  1205.         loss = ((total >= eshkp->robbed) ? total : eshkp->robbed);
  1206.         take = TRUE;
  1207.     }
  1208.  
  1209.     if (eshkp->following || ANGRY(shkp) || take) {
  1210.  
  1211.         if(!invent && !u.ugold) goto skip;
  1212.  
  1213.         if((loss > u.ugold) || !loss) {
  1214.             pline("%s %s%stakes all your possessions.",
  1215.                 shkname(shkp),
  1216.                 (shkp->msleep || shkp->mfrozen) ?
  1217.                    "wakes up and " : "",
  1218.                 (distu(shkp->mx, shkp->my) > 2) ?
  1219.                     "comes and " : "");
  1220.             taken = TRUE;
  1221.             shkp->mgold += u.ugold;
  1222.             u.ugold = 0L;
  1223.             /* in case bones: make it be for real... */
  1224.             if(!*u.ushops ||
  1225.                  IS_DOOR(levl[u.ux][u.uy].typ)) {
  1226.                 /* shk.x,shk.y is the position immediately in
  1227.                  * front of the door -- move in one more space
  1228.                  */
  1229.                 ox = eshkp->shk.x;
  1230.                 oy = eshkp->shk.y;
  1231.                 ox += sgn(ox - eshkp->shd.x);
  1232.                 oy += sgn(oy - eshkp->shd.y);
  1233.             } else {
  1234.                 ox = u.ux;
  1235.                 oy = u.uy;
  1236.             }
  1237.  
  1238.             if (invent) {
  1239.                 for(otmp = invent; otmp; otmp = otmp->nobj)
  1240.                 place_object(otmp, ox, oy);
  1241.  
  1242.                 /* add to main object list at end so invent is
  1243.                    still good */
  1244.                 if (fobj) {
  1245.                 otmp = fobj;
  1246.                 while(otmp->nobj)
  1247.                     otmp = otmp->nobj;
  1248.                 otmp->nobj = invent;
  1249.                 } else
  1250.                 fobj = invent;
  1251.             }
  1252.         } else {
  1253.             u.ugold -= loss;
  1254.             shkp->mgold += loss;
  1255.             pline("%s %sand takes %ld zorkmid%s %sowed %s.",
  1256.                   Monnam(shkp),
  1257.                   (shkp->msleep || shkp->mfrozen) ?
  1258.                     "wakes up " : "comes ",
  1259.                   loss, plur(loss),
  1260.                   strncmp(eshkp->customer,
  1261.                        plname, PL_NSIZ) ? "" : "you ",
  1262.                   shkp->female ? "her" : "him");
  1263.         }
  1264. skip:
  1265.         /* in case we create bones */
  1266.         if(!inhishop(shkp))
  1267.             home_shk(shkp, FALSE);
  1268.     }
  1269. clear:
  1270.     setpaid(shkp);
  1271.     return(taken);
  1272. }
  1273.  
  1274. /* find obj on one of the lists */
  1275. static struct obj *
  1276. bp_to_obj(bp)
  1277. register struct bill_x *bp;
  1278. {
  1279.     register struct obj *obj;
  1280.     register struct monst *mtmp;
  1281.     register unsigned int id = bp->bo_id;
  1282.  
  1283.     if(bp->useup)
  1284.         obj = o_on(id, billobjs);
  1285.     else if(!(obj = o_on(id, invent)) &&
  1286.         !(obj = o_on(id, fobj)) &&
  1287.         !(obj = o_on(id, migrating_objs))) {
  1288.             for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  1289.             if ((obj = o_on(id, mtmp->minvent)) != 0)
  1290.                 return obj;
  1291.             for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon)
  1292.             if ((obj = o_on(id, mtmp->minvent)) != 0)
  1293.                 return obj;
  1294.         }
  1295.     return(obj);
  1296. }
  1297.  
  1298. /* calculate the value that the shk will charge for [one of] an object */
  1299. static long
  1300. get_cost(obj, shkp)
  1301. register struct obj *obj;
  1302. register struct monst *shkp;    /* if angry, impose a surcharge */
  1303. {
  1304.     register long tmp = getprice(obj);
  1305.  
  1306.     if (!tmp) tmp = 5L;
  1307.     /* shopkeeper may notice if the player isn't very knowledgeable -
  1308.        especially when gem prices are concerned */
  1309.     if (!objects[obj->otyp].oc_name_known)
  1310.         if (obj->oclass == GEM_CLASS) {
  1311.             /* all gems are priced high - real or not */
  1312.             if (objects[obj->otyp].oc_material == GLASS) {
  1313.                 /* real gem's cost (worthless gems come
  1314.                    after jade but before luckstone) */
  1315.                 tmp = (long)objects[
  1316.                     obj->otyp - LUCKSTONE + JADE + 1].oc_cost;
  1317.             }
  1318.         } else if (!(obj->o_id % 4)) /* arbitrarily impose surcharge */
  1319.             tmp += tmp / 3L;
  1320. #ifdef TOURIST
  1321.     if((pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))
  1322.         || (uarmu && !uarm && !uarmc))    /* Hawaiian shirt visible */
  1323.         tmp += tmp / 3L;
  1324. #endif
  1325.     if (ACURR(A_CHA) > 18)        tmp /= 2L;
  1326.     else if (ACURR(A_CHA) > 17)    tmp -= tmp / 3L;
  1327.     else if (ACURR(A_CHA) > 15)    tmp -= tmp / 4L;
  1328.     else if (ACURR(A_CHA) < 6)    tmp *= 2L;
  1329.     else if (ACURR(A_CHA) < 8)    tmp += tmp / 2L;
  1330.     else if (ACURR(A_CHA) < 11)    tmp += tmp / 3L;
  1331.     if (tmp <= 0L) tmp = 1L;
  1332.     else if (obj->oartifact) tmp *= 4L;
  1333.     /* anger surcharge should match rile_shk's */
  1334.     if (shkp && ESHK(shkp)->surcharge) tmp += (tmp + 2L) / 3L;
  1335.     return tmp;
  1336. }
  1337.  
  1338. /* returns the price of a container's content.  the price
  1339.  * of the "top" container is added in the calling functions.
  1340.  * a different price quoted for selling as vs. buying.
  1341.  */
  1342. long
  1343. contained_cost(obj, shkp, price, usell)
  1344. register struct obj *obj;
  1345. register struct monst *shkp;
  1346. long price;
  1347. register boolean usell;
  1348. {
  1349.     register struct obj *otmp;
  1350.  
  1351.     /* the price of contained objects */
  1352.     for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1353.         register boolean goods = saleable(rooms[ESHK(shkp)->shoproom -
  1354.                        ROOMOFFSET].rtype-SHOPBASE, otmp);
  1355.  
  1356.         if(otmp->otyp == GOLD_PIECE) continue;
  1357.  
  1358.         /* the "top" container is evaluated by caller */
  1359.         if(usell) {
  1360.         if(goods && !otmp->unpaid &&
  1361.             otmp->oclass != BALL_CLASS &&
  1362.             !(otmp->oclass == FOOD_CLASS && otmp->oeaten) &&
  1363.             !(Is_candle(otmp) && otmp->age <
  1364.                 20L * (long)objects[otmp->otyp].oc_cost))
  1365.             price += set_cost(otmp, shkp);
  1366.         } else if(!otmp->no_charge) {
  1367.             price += get_cost(otmp, shkp);
  1368.         }
  1369.  
  1370.         if(Is_container(otmp))
  1371.             price += contained_cost(otmp, shkp, price, usell);
  1372.     }
  1373.  
  1374.     return(price);
  1375. }
  1376.  
  1377. long
  1378. contained_gold(obj)
  1379. register struct obj *obj;
  1380. {
  1381.     register struct obj *otmp;
  1382.     register long value = 0L;
  1383.  
  1384.     /* accumulate contained gold */
  1385.     for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
  1386.         if (otmp->otyp == GOLD_PIECE)
  1387.         value += otmp->quan;
  1388.         else if (Is_container(otmp))
  1389.         value += contained_gold(otmp);
  1390.  
  1391.     return(value);
  1392. }
  1393.  
  1394. static void
  1395. dropped_container(obj)
  1396. register struct obj *obj;
  1397. {
  1398.     register struct obj *otmp;
  1399.  
  1400.     /* the "top" container is treated in the calling fn */
  1401.     for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1402.  
  1403.         if(otmp->otyp == GOLD_PIECE) continue;
  1404.  
  1405.         if(!otmp->unpaid)
  1406.         otmp->no_charge = 1;
  1407.  
  1408.         if(Is_container(otmp))
  1409.         dropped_container(otmp);
  1410.     }
  1411. }
  1412.  
  1413. void
  1414. picked_container(obj)
  1415. register struct obj *obj;
  1416. {
  1417.     register struct obj *otmp;
  1418.  
  1419.     /* the "top" container is treated in the calling fn */
  1420.     for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1421.  
  1422.         if(otmp->otyp == GOLD_PIECE) continue;
  1423.  
  1424.         if(otmp->no_charge)
  1425.         otmp->no_charge = 0;
  1426.  
  1427.         if(Is_container(otmp))
  1428.         picked_container(otmp);
  1429.     }
  1430. }
  1431.  
  1432. /* calculate how much the shk will pay when buying [all of] an object */
  1433. static long
  1434. set_cost(obj, shkp)
  1435. register struct obj *obj;
  1436. register struct monst *shkp;
  1437. {
  1438.     long tmp = getprice(obj) * obj->quan;
  1439.  
  1440. #ifdef TOURIST
  1441.     if ((pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))
  1442.         || (uarmu && !uarm && !uarmc))    /* Hawaiian shirt visible */
  1443.         tmp /= 3L;
  1444.     else
  1445. #endif
  1446.         tmp /= 2L;
  1447.     /* shopkeeper may notice if the player isn't very knowledgeable -
  1448.        especially when gem prices are concerned */
  1449.     if (!objects[obj->otyp].oc_name_known) {
  1450.         if (obj->oclass == GEM_CLASS) {
  1451.             /* different shop keepers give different prices */
  1452.             if (objects[obj->otyp].oc_material == GEMSTONE ||
  1453.                 objects[obj->otyp].oc_material == GLASS) {
  1454.                 tmp = (obj->otyp % (6 - shkp->m_id % 3));
  1455.                 tmp = (tmp + 3) * obj->quan;
  1456.             }
  1457.         } else if (tmp > 1L && !rn2(4))
  1458.             tmp -= tmp / 4L;
  1459.     }
  1460.     return tmp;
  1461. }
  1462.  
  1463. /* called from doinv(invent.c) for inventory of unpaid objects */
  1464. long
  1465. unpaid_cost(unp_obj)
  1466. register struct obj *unp_obj;    /* known to be unpaid */
  1467. {
  1468.     register struct bill_x *bp = (struct bill_x *)0;
  1469.     register struct monst *shkp;
  1470.  
  1471.     for(shkp = next_shkp(fmon, TRUE); shkp;
  1472.                     shkp = next_shkp(shkp->nmon, TRUE))
  1473.         if ((bp = onbill(unp_obj, shkp, TRUE)) != 0) break;
  1474.  
  1475.     /* onbill() gave no message if unexpected problem occurred */
  1476.     if(!bp) impossible("unpaid_cost: object wasn't on any bill!");
  1477.  
  1478.     return bp ? unp_obj->quan * bp->price : 0L;
  1479. }
  1480.  
  1481. static void
  1482. add_one_tobill(obj, dummy)
  1483. register struct obj *obj;
  1484. register boolean dummy;
  1485. {
  1486.     register struct monst *shkp;
  1487.     register struct bill_x *bp;
  1488.     register int bct;
  1489.     register char roomno = *u.ushops;
  1490.  
  1491.     if(!*u.ushops) return;
  1492.  
  1493.     if(!(shkp = shop_keeper(roomno))) return;
  1494.  
  1495.     if(!inhishop(shkp)) return;
  1496.  
  1497.     if(onbill(obj, shkp, FALSE) || /* perhaps thrown away earlier */
  1498.             (obj->oclass == FOOD_CLASS && obj->oeaten))
  1499.         return;
  1500.  
  1501.     if(ESHK(shkp)->billct == BILLSZ) {
  1502.         You("got that for free!");
  1503.         return;
  1504.     }
  1505.  
  1506.     /* To recognize objects the shopkeeper is not interested in. -dgk
  1507.      */
  1508.     if (obj->no_charge) {
  1509.         obj->no_charge = 0;
  1510.         return;
  1511.     }
  1512.  
  1513.     bct = ESHK(shkp)->billct;
  1514.     bp = &(ESHK(shkp)->bill_p[bct]);
  1515.     bp->bo_id = obj->o_id;
  1516.     bp->bquan = obj->quan;
  1517.     if(dummy) {          /* a dummy object must be inserted into  */
  1518.         bp->useup = 1;      /* the billobjs chain here.  crucial for */
  1519.         obj->nobj = billobjs; /* eating floorfood in shop.  see eat.c  */
  1520.         billobjs = obj;
  1521.     } else    bp->useup = 0;
  1522.     bp->price = get_cost(obj, shkp);
  1523.     ESHK(shkp)->billct++;
  1524.     obj->unpaid = 1;
  1525. }
  1526.  
  1527. /* recursive billing of objects within containers. */
  1528. static void
  1529. bill_box_content(obj, ininv, dummy, shkp)
  1530. register struct obj *obj;
  1531. register boolean ininv, dummy;
  1532. register struct monst *shkp;
  1533. {
  1534.     register struct obj *otmp;
  1535.  
  1536.     for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1537.  
  1538.         if(obj->otyp == GOLD_PIECE) continue;
  1539.         /* the "top" box is added in addtobill() */
  1540.         if(!otmp->no_charge)
  1541.             add_one_tobill(otmp, dummy);
  1542.         if(Is_container(otmp))
  1543.             bill_box_content(otmp, ininv, dummy, shkp);
  1544.     }
  1545.  
  1546. }
  1547.  
  1548. void
  1549. addtobill(obj, ininv, dummy, silent)
  1550. register struct obj *obj;
  1551. register boolean ininv, dummy, silent;
  1552. {
  1553.     register struct monst *shkp;
  1554.     register char roomno = *u.ushops;
  1555.     long ltmp = 0L, cltmp = 0L, gltmp = 0L;
  1556.     register boolean container = Is_container(obj);
  1557.  
  1558.     if(!*u.ushops) return;
  1559.  
  1560.     if(!(shkp = shop_keeper(roomno))) return;
  1561.  
  1562.     if(!inhishop(shkp)) return;
  1563.  
  1564.     if(/* perhaps we threw it away earlier */
  1565.          onbill(obj, shkp, FALSE) ||
  1566.          (obj->oclass == FOOD_CLASS && obj->oeaten)
  1567.           ) return;
  1568.  
  1569.     if(ESHK(shkp)->billct == BILLSZ) {
  1570.         You("got that for free!");
  1571.         return;
  1572.     }
  1573.  
  1574.     if(obj->oclass == GOLD_CLASS) {
  1575.         costly_gold(obj->ox, obj->oy, obj->quan);
  1576.         return;
  1577.     }
  1578.  
  1579.     if(!obj->no_charge) ltmp = get_cost(obj, shkp);
  1580.  
  1581.     if (obj->no_charge && !container) {
  1582.         obj->no_charge = 0;
  1583.         return;
  1584.     }
  1585.  
  1586.     if(container) {
  1587.         if(obj->cobj == (struct obj *)0) {
  1588.         if(obj->no_charge) {
  1589.             obj->no_charge = 0;
  1590.             return;
  1591.         } else {
  1592.             add_one_tobill(obj, dummy);
  1593.             goto speak;
  1594.         }
  1595.         } else {
  1596.         cltmp += contained_cost(obj, shkp, cltmp, FALSE);
  1597.         gltmp += contained_gold(obj);
  1598.         }
  1599.  
  1600.         if(ltmp) add_one_tobill(obj, dummy);
  1601.         if(cltmp) bill_box_content(obj, ininv, dummy, shkp);
  1602.         picked_container(obj); /* reset contained obj->no_charge */
  1603.  
  1604.         ltmp += cltmp;
  1605.  
  1606.         if(gltmp) {
  1607.         costly_gold(obj->ox, obj->oy, gltmp);
  1608.         if(!ltmp) return;
  1609.         }
  1610.  
  1611.         if(obj->no_charge)
  1612.         obj->no_charge = 0;
  1613.  
  1614.     } else /* i.e., !container */
  1615.         add_one_tobill(obj, dummy);
  1616. speak:
  1617.     if(!shkp->msleep && !shkp->mfrozen && !silent) {
  1618.         char buf[BUFSZ];
  1619.  
  1620.         if(!ltmp) {
  1621.         pline("%s has no interest in %s.", Monnam(shkp),
  1622.                          the(xname(obj)));
  1623.         return;
  1624.         }
  1625.         Strcpy(buf, "\"For you, ");
  1626.         if (ANGRY(shkp)) Strcat(buf, "scum ");
  1627.         else {
  1628.         switch(rnd(4) + u.uevent.udemigod) {
  1629.           case 1: Strcat(buf, "good");
  1630.               break;
  1631.           case 2: Strcat(buf, "honored");
  1632.               break;
  1633.           case 3: Strcat(buf, "most gracious");
  1634.               break;
  1635.           case 4: Strcat(buf, "esteemed");
  1636.               break;
  1637.           case 5: Strcat(buf, "most renowned and sacred");
  1638.               break;
  1639.         }
  1640. #ifdef POLYSELF
  1641.         if(!is_human(uasmon)) Strcat(buf, " creature");
  1642.         else
  1643. #endif
  1644.             Strcat(buf, (flags.female) ? " lady" : " sir");
  1645.         }
  1646.         /* after all, the shk is telling you what it is */
  1647.         obj->dknown = 1;
  1648.         exercise(A_WIS, TRUE);
  1649.         if(ininv) {
  1650.         long quan = obj->quan;
  1651.         obj->quan = 1L; /* fool xname() into giving singular */
  1652.         pline("%s; only %ld %s %s.\"", buf, ltmp,
  1653.             (quan > 1L) ? "per" : "for this", xname(obj));
  1654.         obj->quan = quan;
  1655.         } else
  1656.         pline("%s will cost you %ld zorkmid%s%s.",
  1657.             The(xname(obj)), ltmp, plur(ltmp),
  1658.             (obj->quan > 1L) ? " each" : "");
  1659.     } else if(!silent) {
  1660.         if(ltmp) pline("The list price of %s is %ld zorkmid%s%s.",
  1661.                    the(xname(obj)), ltmp, plur(ltmp),
  1662.                    (obj->quan > 1L) ? " each" : "");
  1663.         else pline("%s does not notice.", Monnam(shkp));
  1664.     }
  1665. }
  1666.  
  1667. void
  1668. splitbill(obj, otmp)
  1669. register struct obj *obj, *otmp;
  1670. {
  1671.     /* otmp has been split off from obj */
  1672.     register struct bill_x *bp;
  1673.     register long tmp;
  1674.     register struct monst *shkp = shop_keeper(*u.ushops);
  1675.  
  1676.     if(!shkp || !inhishop(shkp)) {
  1677.         impossible("splitbill: no resident shopkeeper??");
  1678.         return;
  1679.     }
  1680.     bp = onbill(obj, shkp, FALSE);
  1681.     if(!bp) {
  1682.         impossible("splitbill: not on bill?");
  1683.         return;
  1684.     }
  1685.     if(bp->bquan < otmp->quan) {
  1686.         impossible("Negative quantity on bill??");
  1687.     }
  1688.     if(bp->bquan == otmp->quan) {
  1689.         impossible("Zero quantity on bill??");
  1690.     }
  1691.     bp->bquan -= otmp->quan;
  1692.  
  1693.     if(ESHK(shkp)->billct == BILLSZ) otmp->unpaid = 0;
  1694.     else {
  1695.         tmp = bp->price;
  1696.         bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
  1697.         bp->bo_id = otmp->o_id;
  1698.         bp->bquan = otmp->quan;
  1699.         bp->useup = 0;
  1700.         bp->price = tmp;
  1701.         ESHK(shkp)->billct++;
  1702.     }
  1703. }
  1704.  
  1705. static void
  1706. sub_one_frombill(obj, shkp)
  1707. register struct obj *obj;
  1708. register struct monst *shkp;
  1709. {
  1710.     register struct bill_x *bp;
  1711.  
  1712.     if((bp = onbill(obj, shkp, FALSE)) != 0) {
  1713.         register struct obj *otmp;
  1714.  
  1715.         obj->unpaid = 0;
  1716.         if(bp->bquan > obj->quan){
  1717.             otmp = newobj(0);
  1718.             *otmp = *obj;
  1719.             bp->bo_id = otmp->o_id = flags.ident++;
  1720.             otmp->quan = (bp->bquan -= obj->quan);
  1721.             otmp->owt = 0;    /* superfluous */
  1722.             otmp->onamelth = 0;
  1723.             bp->useup = 1;
  1724.             otmp->nobj = billobjs;
  1725.             billobjs = otmp;
  1726.             return;
  1727.         }
  1728.         ESHK(shkp)->billct--;
  1729. #ifdef DUMB
  1730.         {
  1731.         /* DRS/NS 2.2.6 messes up -- Peter Kendell */
  1732.             int indx = ESHK(shkp)->billct;
  1733.             *bp = ESHK(shkp)->bill_p[indx];
  1734.         }
  1735. #else
  1736.         *bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
  1737. #endif
  1738.         return;
  1739.     } else if (obj->unpaid) {
  1740.         impossible("sub_one_frombill: unpaid object not on bill");
  1741.         obj->unpaid = 0;
  1742.     }
  1743. }
  1744.  
  1745. /* recursive check of unpaid objects within nested containers. */
  1746. void
  1747. subfrombill(obj, shkp)
  1748. register struct obj *obj;
  1749. register struct monst *shkp;
  1750. {
  1751.     register struct obj *otmp;
  1752.  
  1753.     sub_one_frombill(obj, shkp);
  1754.  
  1755.     if(Is_container(obj))
  1756.         for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1757.         if(otmp->otyp == GOLD_PIECE) continue;
  1758.  
  1759.         if(Is_container(otmp))
  1760.             subfrombill(otmp, shkp);
  1761.         else
  1762.             sub_one_frombill(otmp, shkp);
  1763.         }
  1764. }
  1765.  
  1766. static long
  1767. stolen_container(obj, shkp, price, ininv)
  1768. register struct obj *obj;
  1769. register struct monst *shkp;
  1770. long price;
  1771. register boolean ininv;
  1772. {
  1773.     register struct obj *otmp;
  1774.  
  1775.     if(ininv && obj->unpaid)
  1776.         price += get_cost(obj, shkp);
  1777.     else {
  1778.         if(!obj->no_charge)
  1779.         price += get_cost(obj, shkp);
  1780.         obj->no_charge = 0;
  1781.     }
  1782.  
  1783.     /* the price of contained objects, if any */
  1784.     for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
  1785.  
  1786.         if(otmp->otyp == GOLD_PIECE) continue;
  1787.  
  1788.         if(!Is_container(otmp)) {
  1789.         if(ininv) {
  1790.             if(otmp->unpaid)
  1791.             price += get_cost(otmp, shkp);
  1792.         } else {
  1793.             if(!otmp->no_charge) {
  1794.             if(!(otmp->oclass == BALL_CLASS ||
  1795.                 (otmp->oclass == FOOD_CLASS && otmp->oeaten) ||
  1796.                 (Is_candle(otmp) && otmp->age <
  1797.                   20L * (long)objects[otmp->otyp].oc_cost))
  1798.               ) price += get_cost(otmp, shkp);
  1799.             }
  1800.             otmp->no_charge = 0;
  1801.         }
  1802.         } else
  1803.         price += stolen_container(otmp, shkp, price, ininv);
  1804.     }
  1805.  
  1806.     return(price);
  1807. }
  1808.  
  1809. long
  1810. stolen_value(obj, x, y, peaceful, silent)
  1811. register struct obj *obj;
  1812. register xchar x, y;
  1813. register boolean peaceful, silent;
  1814. {
  1815.     register long value = 0L, gvalue = 0L;
  1816.     register struct monst *shkp;
  1817.     register boolean goods;
  1818.  
  1819.     shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
  1820.  
  1821.     if (!shkp || !inhishop(shkp))
  1822.         return (0L);
  1823.  
  1824.     goods = saleable(rooms[ESHK(shkp)->shoproom -
  1825.                    ROOMOFFSET].rtype-SHOPBASE, obj);
  1826.     goods = (goods && !obj->no_charge);
  1827.  
  1828.     if(obj->otyp == GOLD_PIECE) {
  1829.         gvalue += obj->quan;
  1830.     } else if(Is_container(obj)) {
  1831.         register boolean ininv = !!count_unpaid(obj->cobj);
  1832.  
  1833.         value += stolen_container(obj, shkp, value, ininv);
  1834.         if(!ininv) gvalue += contained_gold(obj);
  1835.     } else if(goods) {
  1836.         value += get_cost(obj, shkp);
  1837.     }
  1838.  
  1839.     if(gvalue + value == 0L) return(0L);
  1840.  
  1841.     value += gvalue;
  1842.  
  1843.     if(peaceful) {
  1844.         value = check_credit(value, shkp);
  1845.         ESHK(shkp)->debit += value;
  1846.  
  1847.         if(!silent) {
  1848.         if(obj->otyp == GOLD_PIECE)
  1849.             You("owe %s %ld zorkmids!", mon_nam(shkp), value);
  1850.         else You("owe %s %ld zorkmids for %s!",
  1851.             mon_nam(shkp),
  1852.             value,
  1853.             obj->quan > 1L ? "them" : "it");
  1854.         }
  1855.     } else {
  1856.         ESHK(shkp)->robbed += value;
  1857.  
  1858.         if(!silent) {
  1859.         if(cansee(shkp->mx, shkp->my)) {
  1860.             if(ESHK(shkp)->customer[0] == 0)
  1861.             (void) strncpy(ESHK(shkp)->customer,plname,PL_NSIZ);
  1862.             Norep("%s booms: \"%s, you are a thief!\"",
  1863.                 Monnam(shkp), plname);
  1864.         } else  Norep("You hear a scream, \"Thief!\"");
  1865.         }
  1866.         hot_pursuit(shkp);
  1867.         (void) angry_guards(FALSE);
  1868.     }
  1869.     return(value);
  1870. }
  1871.  
  1872. /* auto-response flag for/from "sell foo?" 'a' => 'y', 'q' => 'n' */
  1873. static char sell_response = 'a';
  1874.  
  1875. void
  1876. sellobj_state(deliberate)    /* called from dodrop(do.c) and doddrop() */
  1877. register boolean deliberate;
  1878. {
  1879.     /* If we're deliberately dropping something, there's no automatic
  1880.     response to the shopkeeper's "want to sell" query; however, if we
  1881.     accidentally drop anything, the shk will buy it/them without asking.
  1882.     This retains the old pre-query risk that slippery fingers while in
  1883.     shops entailed:  you drop it, you've lost it.
  1884.      */
  1885.     sell_response = deliberate ? '\0' : 'a';
  1886. }
  1887.  
  1888. void
  1889. sellobj(obj, x, y)
  1890. register struct obj *obj;
  1891. register xchar x, y;
  1892. {
  1893.     register struct monst *shkp;
  1894.     register struct eshk *eshkp;
  1895.     register long ltmp = 0L, cltmp = 0L, gltmp = 0L, offer;
  1896.     boolean saleitem, cgold = FALSE, container = Is_container(obj);
  1897.     boolean isgold = (obj->oclass == GOLD_CLASS);
  1898.  
  1899.     if(!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) ||
  1900.        !inhishop(shkp)) return;
  1901.     if(!costly_spot(x, y))    return;
  1902.     if(!*u.ushops) return;
  1903.  
  1904.     saleitem = saleable(rooms[ESHK(shkp)->shoproom -
  1905.                     ROOMOFFSET].rtype-SHOPBASE, obj);
  1906.  
  1907.     if(obj->unpaid && !container && !isgold) {
  1908.         sub_one_frombill(obj, shkp);
  1909.         return;
  1910.     }
  1911.     if(container) {
  1912.         if(obj->cobj == (struct obj *)0) {
  1913.         if(obj->unpaid) {
  1914.             sub_one_frombill(obj, shkp);
  1915.             return;
  1916.         }
  1917.         } else {
  1918.         /* find the price of content before subfrombill */
  1919.         cltmp += contained_cost(obj, shkp, cltmp, TRUE);
  1920.         /* find the value of contained gold */
  1921.         gltmp += contained_gold(obj);
  1922.         cgold = (gltmp > 0L);
  1923.         }
  1924.     }
  1925.  
  1926.     if(!isgold && !obj->unpaid && saleitem)
  1927.         ltmp = set_cost(obj, shkp);
  1928.  
  1929.     offer = ltmp + cltmp;
  1930.  
  1931.     if(!isgold && (offer + gltmp) == 0L) {
  1932.         register boolean unpaid = (obj->unpaid ||
  1933.                   (container && count_unpaid(obj->cobj)));
  1934.  
  1935.         if(container) {
  1936.             if(obj->cobj != (struct obj *)0) {
  1937.             dropped_container(obj);
  1938.             if(obj->unpaid || count_unpaid(obj->cobj))
  1939.                 subfrombill(obj, shkp);
  1940.             } else obj->no_charge = 1;
  1941.         } else obj->no_charge = 1;
  1942.  
  1943.         if(!unpaid)
  1944.             pline("%s seems uninterested.", Monnam(shkp));
  1945.         return;
  1946.     }
  1947.  
  1948.     /* you dropped something of your own - probably want to sell it */
  1949.     if(shkp->msleep || !shkp->mcanmove) {
  1950.         if(container && obj->cobj != (struct obj *)0) {
  1951.             dropped_container(obj);
  1952.         }
  1953.         if(!shkp->mcanmove) {
  1954.             if(ANGRY(shkp) && !rn2(4))
  1955.             pline("%s utters a curse.", Monnam(shkp));
  1956.             else pline("%s is indisposed.", Monnam(shkp));
  1957.         } else if(!rn2(3)) {
  1958.             pline("%s snores indifferently.", Monnam(shkp));
  1959.         }
  1960.         subfrombill(obj, shkp);
  1961.         return;
  1962.     }
  1963.  
  1964.     eshkp = ESHK(shkp);
  1965.  
  1966.     if(isgold || cgold) {
  1967.         if(ANGRY(shkp)) {
  1968.             if(!offer) {
  1969.              pline("%s is not appeased.", Monnam(shkp));
  1970.              if(cgold) subfrombill(obj, shkp);
  1971.              return;
  1972.             } else goto move_on;
  1973.         }
  1974.  
  1975.         if(!cgold) gltmp = obj->quan;
  1976.  
  1977.         if(eshkp->debit >= gltmp) {
  1978.             if(eshkp->loan) { /* you carry shop's gold */
  1979.              if(eshkp->loan >= gltmp)
  1980.                  eshkp->loan -= gltmp;
  1981.              else eshkp->loan = 0L;
  1982.             }
  1983.             eshkp->debit -= gltmp;
  1984.             Your("debt is %spaid off.",
  1985.                 eshkp->debit ? "partially " : "");
  1986.         } else {
  1987.             long delta = gltmp - eshkp->debit;
  1988.  
  1989.             eshkp->credit += delta;
  1990.             if(eshkp->debit) {
  1991.             eshkp->debit = 0L;
  1992.             eshkp->loan = 0L;
  1993.             Your("debt is paid off.");
  1994.             }
  1995.             pline("%ld zorkmid%s added to your credit.",
  1996.                 delta, delta > 1L ? "s are" : " is");
  1997.         }
  1998.         if(offer) goto move_on;
  1999.         else {
  2000.             if(container && obj->cobj != (struct obj *)0) {
  2001.             dropped_container(obj);
  2002.             }
  2003.             subfrombill(obj, shkp);
  2004.             obj->no_charge = 1;
  2005.             return;
  2006.         }
  2007.     }
  2008. move_on:
  2009.     if (ANGRY(shkp)) { /* they become shop-objects, no pay */
  2010.         pline("Thank you, scum!");
  2011.         subfrombill(obj, shkp);
  2012.         return;
  2013.     }
  2014.  
  2015.     if((!saleitem && !(container && cltmp > 0L))
  2016.        || eshkp->billct == BILLSZ
  2017.        || obj->oclass == BALL_CLASS || offer == 0L
  2018.        || (obj->oclass == FOOD_CLASS && obj->oeaten)
  2019.        || (Is_candle(obj) &&
  2020.            obj->age < 20L * (long)objects[obj->otyp].oc_cost)) {
  2021.         pline("%s seems not interested%s.", Monnam(shkp),
  2022.                        cgold ? " in the rest" : "");
  2023.         if(container && obj->cobj != (struct obj *)0) {
  2024.             dropped_container(obj);
  2025.         }
  2026.         obj->no_charge = 1;
  2027.         return;
  2028.     }
  2029.  
  2030.     if(eshkp->robbed) {  /* shkp is not angry? */
  2031.         if((eshkp->robbed -= offer < 0L))
  2032.             eshkp->robbed = 0L;
  2033.         verbalize(
  2034.   "Thank you for your contribution to restock this recently plundered shop.");
  2035.         subfrombill(obj, shkp);
  2036.         return;
  2037.     }
  2038.  
  2039.     if(!shkp->mgold) {
  2040.         long tmpcr = (ltmp + cltmp) * 2L;
  2041.  
  2042.         pline("%s cannot pay you at present.", Monnam(shkp));
  2043.         pline("Will you accept %ld zorkmids in credit for %s? ",
  2044.                      tmpcr, doname(obj));
  2045.         /* cannot use a yn function here */
  2046.         if (readchar() == 'y') {
  2047.             You("have %ld zorkmids in %scredit.", tmpcr,
  2048.                 ESHK(shkp)->credit > 0L ? "additional " : "");
  2049.             ESHK(shkp)->credit += tmpcr;
  2050.             subfrombill(obj, shkp);
  2051.         } else {
  2052.             if(container && obj->cobj != (struct obj *)0) {
  2053.                 dropped_container(obj);
  2054.             }
  2055.             subfrombill(obj, shkp);
  2056.             obj->no_charge = 1;
  2057.         }
  2058.     } else {
  2059.         int qlen;
  2060.         char qbuf[BUFSZ];
  2061.         boolean short_funds = (offer > shkp->mgold);
  2062.  
  2063.         if (short_funds) offer = shkp->mgold;
  2064.  
  2065.         if (!sell_response) {
  2066.             Sprintf(qbuf,
  2067.                 "%s offers%s %ld gold piece%s for%s your %s.",
  2068.                 Monnam(shkp), short_funds ? " only" : "",
  2069.                 offer, plur(offer),
  2070.                 (!ltmp && cltmp) ? " the contents of" : "",
  2071.                 xname(obj));
  2072.             qlen = strlen(qbuf);
  2073.             /*  Will the prompt fit on the topline? (or would
  2074.              *    "--more--" force line wrap anyway?)  If so, combine
  2075.              *    the message and prompt; otherwise, flush message
  2076.              *    and prompt separately.
  2077.              */
  2078.             if (qlen > COLNO - 24 && qlen <= COLNO - 8)
  2079.             pline(qbuf),  qbuf[0] = '\0';
  2080.             else  Strcat(qbuf, "  ");
  2081.             Strcat(strcat(qbuf, "Sell "),
  2082.                 (obj->quan == 1L ? "it?" : "them?"));
  2083.         } else  qbuf[0] = '\0';        /* just to pacify lint */
  2084.  
  2085.         switch (sell_response ? sell_response : ynaq(qbuf)) {
  2086.          case 'q':  sell_response = 'n';
  2087.          case 'n':  if(container && obj->cobj != (struct obj *)0) {
  2088.                 dropped_container(obj);
  2089.                 }
  2090.                 subfrombill(obj, shkp);
  2091.                 obj->no_charge = 1;
  2092.                 break;
  2093.          case 'a':  sell_response = 'y';
  2094.          case 'y':  subfrombill(obj, shkp);
  2095.                 pay(-offer, shkp);
  2096.                 You("sold %s for %ld gold piece%s.", doname(obj),
  2097.                 offer, plur(offer));
  2098.                 break;
  2099.          default:   impossible("invalid sell response");
  2100.         }
  2101.     }
  2102. }
  2103.  
  2104. int
  2105. doinvbill(mode)
  2106. int mode;        /* 0: deliver count 1: paged */
  2107. {
  2108.     register struct monst* shkp;
  2109.     register struct bill_x *bp, *end_bp;
  2110.     register struct obj *obj;
  2111.     long totused;
  2112.     char *buf_p;
  2113.     winid datawin;
  2114.  
  2115.     shkp = shop_keeper(*u.ushops);
  2116.  
  2117.     if(mode == 0) {
  2118.         register int cnt = 0;
  2119.  
  2120.         if(shkp && inhishop(shkp))
  2121.         for (bp = ESHK(shkp)->bill_p,
  2122.             end_bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
  2123.             bp < end_bp; bp++)
  2124.             if(bp->useup ||
  2125.                ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan))
  2126.             cnt++;
  2127.         return(cnt);
  2128.     }
  2129.  
  2130.     if(!shkp || !inhishop(shkp)) {
  2131.         impossible("doinvbill: no shopkeeper?");
  2132.         return(0);
  2133.     }
  2134.  
  2135.     datawin = create_nhwindow(NHW_MENU);
  2136.     putstr(datawin, 0, "Unpaid articles already used up:");
  2137.     putstr(datawin, 0, "");
  2138.  
  2139.     totused = 0L;
  2140.     for (bp = ESHK(shkp)->bill_p,
  2141.         end_bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
  2142.         bp < end_bp; bp++) {
  2143.         obj = bp_to_obj(bp);
  2144.         if(!obj) {
  2145.         impossible("Bad shopkeeper administration.");
  2146.         goto quit;
  2147.         }
  2148.         if(bp->useup || bp->bquan > obj->quan) {
  2149.         register long oquan, uquan;
  2150.         long thisused;
  2151.  
  2152.         oquan = obj->quan;
  2153.         uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
  2154.         thisused = bp->price * uquan;
  2155.         totused += thisused;
  2156.         obj->quan = uquan;        /* cheat doname */
  2157.         buf_p = xprname(obj, ' ', FALSE, thisused);
  2158.         obj->quan = oquan;        /* restore value */
  2159.         putstr(datawin, 0, buf_p);
  2160.         }
  2161.     }
  2162.     buf_p = xprname((struct obj *)0, '*', FALSE, totused);
  2163.     putstr(datawin, 0, "");
  2164.     putstr(datawin, 0, buf_p);
  2165.     display_nhwindow(datawin, FALSE);
  2166.     quit:
  2167.     destroy_nhwindow(datawin);
  2168.     return(0);
  2169. }
  2170.  
  2171. #define HUNGRY    2
  2172.  
  2173. static long
  2174. getprice(obj)
  2175. register struct obj *obj;
  2176. {
  2177.     register long tmp = (long) objects[obj->otyp].oc_cost;
  2178.  
  2179.     switch(obj->oclass) {
  2180.     case FOOD_CLASS:
  2181.         /* simpler hunger check, (2-4)*cost */
  2182.         if (u.uhs >= HUNGRY) tmp *= (long) u.uhs;
  2183.         if (obj->oeaten) tmp = 0L;
  2184.         break;
  2185.     case WAND_CLASS:
  2186.         if (obj->spe == -1) tmp = 0L;
  2187.         break;
  2188.     case POTION_CLASS:
  2189.         if (obj->otyp == POT_WATER && !obj->blessed && !obj->cursed)
  2190.             tmp = 0L;
  2191.         break;
  2192.     case ARMOR_CLASS:
  2193.     case WEAPON_CLASS:
  2194.         if (obj->spe > 0) tmp += 10L * (long) obj->spe;
  2195.         break;
  2196.     case CHAIN_CLASS:
  2197.         pline("Strange... carrying a chain?");
  2198.         break;
  2199.     case TOOL_CLASS:
  2200.         if (Is_candle(obj) &&
  2201.             obj->age < 20L * (long)objects[obj->otyp].oc_cost)
  2202.             tmp /= 2L;
  2203.         break;
  2204.     }
  2205.     if (obj->oartifact) tmp *= 25L;
  2206.     return tmp;
  2207. }
  2208.  
  2209. int
  2210. shkcatch(obj, x, y)
  2211. register struct obj *obj;
  2212. register xchar x, y;
  2213. {
  2214.     register struct monst *shkp;
  2215.  
  2216.     if (!(shkp = shop_keeper(inside_shop(x, y))) ||
  2217.         !inhishop(shkp)) return(0);
  2218.  
  2219.     if (shkp->mcanmove && !shkp->msleep &&
  2220.         (*u.ushops != ESHK(shkp)->shoproom || !inside_shop(u.ux, u.uy)) &&
  2221.         dist2(shkp->mx, shkp->my, x, y) < 3 &&
  2222.         /* if it is the shk's pos, you hit and anger him */
  2223.         (shkp->mx != x || shkp->my != y)) {
  2224.         if (mnearto(shkp, x, y, TRUE))
  2225.             verbalize("Out of my way, scum!");
  2226.         pline("%s nimbly catches %s.", Monnam(shkp), the(xname(obj)));
  2227.         mpickobj(shkp, obj);
  2228.         subfrombill(obj, shkp);
  2229.         return(1);
  2230.     }
  2231.     return(0);
  2232. }
  2233.  
  2234. void
  2235. add_damage(x, y, cost)
  2236. register xchar x, y;
  2237. long cost;
  2238. {
  2239.     struct damage *tmp_dam;
  2240.     char *shops;
  2241.  
  2242.     if (IS_DOOR(levl[x][y].typ))
  2243.         /* Don't schedule for repair unless it's a real shop entrance */
  2244.         for (shops = in_rooms(x, y, SHOPBASE); *shops; shops++) {
  2245.         struct monst *mtmp = shop_keeper(*shops);
  2246.  
  2247.         if (!mtmp)
  2248.             continue;
  2249.         if ((x != ESHK(mtmp)->shd.x) || (y != ESHK(mtmp)->shd.y))
  2250.             return;
  2251.         }
  2252.     tmp_dam = (struct damage *)alloc((unsigned)sizeof(struct damage));
  2253.     tmp_dam->when = monstermoves;
  2254.     tmp_dam->place.x = x;
  2255.     tmp_dam->place.y = y;
  2256.     tmp_dam->cost = cost;
  2257.     tmp_dam->typ = levl[x][y].typ;
  2258.     tmp_dam->next = level.damagelist;
  2259.     level.damagelist = tmp_dam;
  2260.     /* If player saw damage, display as a wall forever */
  2261.     if (cansee(x, y))
  2262.         levl[x][y].seen = 1;
  2263. }
  2264.  
  2265. /*
  2266.  * Do something about damage. Either (!croaked) try to repair it, or
  2267.  * (croaked) just discard damage structs for non-shared locations, since
  2268.  * they'll never get repaired. Assume that shared locations will get
  2269.  * repaired eventually by the other shopkeeper(s). This might be an erroneous
  2270.  * assumption (they might all be dead too), but we have no reasonable way of
  2271.  * telling that.
  2272.  */
  2273. static
  2274. void
  2275. remove_damage(shkp, croaked)
  2276. register struct monst *shkp;
  2277. register boolean croaked;
  2278. {
  2279.     register struct damage *tmp_dam, *tmp2_dam;
  2280.     register boolean did_repair = FALSE, saw_door = FALSE;
  2281.     register boolean saw_floor = FALSE, stop_picking = FALSE;
  2282.     uchar saw_walls = 0;
  2283.  
  2284.     tmp_dam = level.damagelist;
  2285.     tmp2_dam = 0;
  2286.     while (tmp_dam) {
  2287.         register xchar x = tmp_dam->place.x, y = tmp_dam->place.y;
  2288.         char shops[5];
  2289.         uchar disposition;
  2290.  
  2291.         disposition = 0;
  2292.         Strcpy(shops, in_rooms(x, y, SHOPBASE));
  2293.         if (index(shops, ESHK(shkp)->shoproom)) {
  2294.         if (croaked)
  2295.             disposition = (shops[1])? 0 : 1;
  2296.         else if (stop_picking)
  2297.             disposition = repair_damage(shkp, tmp_dam);
  2298.         else {
  2299.             /* Defer the stop_occupation() until after repair msgs */
  2300.             if (closed_door(x, y))
  2301.             stop_picking = picking_at(x, y);
  2302.             disposition = repair_damage(shkp, tmp_dam);
  2303.             if (!disposition)
  2304.             stop_picking = FALSE;
  2305.         }
  2306.         }
  2307.  
  2308.         if (!disposition) {
  2309.         tmp2_dam = tmp_dam;
  2310.         tmp_dam = tmp_dam->next;
  2311.         continue;
  2312.         }
  2313.  
  2314.         if (disposition > 1) {
  2315.         did_repair = TRUE;
  2316.         if (cansee(x, y)) {
  2317.             if (IS_WALL(levl[x][y].typ))
  2318.             saw_walls++;
  2319.             else if (IS_DOOR(levl[x][y].typ))
  2320.             saw_door = TRUE;
  2321.             else
  2322.             saw_floor = TRUE;
  2323.         }
  2324.         }
  2325.  
  2326.         tmp_dam = tmp_dam->next;
  2327.         if (!tmp2_dam) {
  2328.         free((genericptr_t)level.damagelist);
  2329.         level.damagelist = tmp_dam;
  2330.         } else {
  2331.         free((genericptr_t)tmp2_dam->next);
  2332.         tmp2_dam->next = tmp_dam;
  2333.         }
  2334.     }
  2335.     if (!did_repair)
  2336.         return;
  2337.     if (saw_walls) {
  2338.         pline("Suddenly, %s section%s of wall close%s up!",
  2339.           (saw_walls == 1) ? "a" : (saw_walls <= 3) ?
  2340.                           "some" : "several",
  2341.           (saw_walls == 1) ? "" : "s", (saw_walls == 1) ? "s" : "");
  2342.         if (saw_door)
  2343.         pline("The shop door reappears!");
  2344.         if (saw_floor)
  2345.         pline("The floor is repaired!");
  2346.     } else {
  2347.         if (saw_door)
  2348.         pline("Suddenly, the shop door reappears!");
  2349.         else if (saw_floor)
  2350.         pline("Suddenly, the floor damage is gone!");
  2351.         else if (inside_shop(u.ux, u.uy) == ESHK(shkp)->shoproom)
  2352.         You("feel more claustrophobic than before.");
  2353.         else if (flags.soundok && !rn2(10))
  2354.         Norep("The dungeon acoustics noticeably change.");
  2355.     }
  2356.     if (stop_picking)
  2357.         stop_occupation();
  2358. }
  2359.  
  2360. /*
  2361.  * 0: repair postponed, 1: silent repair (no messages), 2: normal repair
  2362.  */
  2363. char
  2364. repair_damage(shkp, tmp_dam)
  2365. register struct monst *shkp;
  2366. register struct damage *tmp_dam;
  2367. {
  2368.     register xchar x, y, i;
  2369.     xchar litter[9];
  2370.     register struct monst *mtmp;
  2371.     register struct obj *otmp;
  2372.     register struct trap *ttmp;
  2373.  
  2374.     if ((monstermoves - tmp_dam->when) < REPAIR_DELAY)
  2375.         return(0);
  2376.     if (ESHK(shkp)->following)
  2377.         return(0);
  2378.     x = tmp_dam->place.x;
  2379.     y = tmp_dam->place.y;
  2380.     if (!IS_ROOM(tmp_dam->typ)) {
  2381.         if ((x == u.ux) && (y == u.uy))
  2382. #ifdef POLYSELF
  2383.         if (!passes_walls(uasmon))
  2384. #endif
  2385.             return(0);
  2386.         if ((x == shkp->mx) && (y == shkp->my))
  2387.         return(0);
  2388.         if ((mtmp = m_at(x, y)) && (!passes_walls(mtmp->data)))
  2389.         return(0);
  2390.     }
  2391.     if ((ttmp = t_at(x, y)) != 0)
  2392.         deltrap(ttmp);
  2393.     if (IS_ROOM(tmp_dam->typ)) {
  2394.         /* No messages if player already filled trapdoor */
  2395.         if (!ttmp)
  2396.         return(1);
  2397.         newsym(x, y);
  2398.         return(2);
  2399.     }
  2400.     if (!ttmp && (tmp_dam->typ == levl[x][y].typ) &&
  2401.         (!IS_DOOR(tmp_dam->typ) || (levl[x][y].doormask > D_BROKEN)))
  2402.         /* No messages if player already replaced shop door */
  2403.         return(1);
  2404.     levl[x][y].typ = tmp_dam->typ;
  2405.     (void) memset((genericptr_t)litter, 0, sizeof(litter));
  2406.     if ((otmp = level.objects[x][y]) != 0) {
  2407.         /* Scatter objects haphazardly into the shop */
  2408. #define NEED_UPDATE 1
  2409. #define OPEN        2
  2410. #define INSHOP        4
  2411. #define horiz(i) ((i%3)-1)
  2412. #define vert(i)  ((i/3)-1)
  2413.         for (i = 0; i < 9; i++) {
  2414.         if ((i == 4) || (!ZAP_POS(levl[x+horiz(i)][y+vert(i)].typ)))
  2415.             continue;
  2416.         litter[i] = OPEN;
  2417.         if (inside_shop(x+horiz(i),
  2418.                 y+vert(i)) == ESHK(shkp)->shoproom)
  2419.             litter[i] |= INSHOP;
  2420.         }
  2421.         if (Punished && ((uchain->ox == x && uchain->oy == y) ||
  2422.                     (uball->ox == x && uball->oy == y))) {
  2423.         /*
  2424.          * Either the ball or chain is in the repair location.
  2425.          *
  2426.          * Take the easy way out and put ball&chain under hero.
  2427.          */
  2428.         verbalize("Get your junk out of my wall!");
  2429.         unplacebc();    /* pick 'em up */
  2430.         placebc();    /* put 'em down */
  2431.         }
  2432.         while ((otmp = level.objects[x][y]) != 0)
  2433.         /* Don't mess w/ boulders -- just merge into wall */
  2434.         if ((otmp->otyp == BOULDER) || (otmp->otyp == ROCK)) {
  2435.             freeobj(otmp);
  2436.             obfree(otmp, (struct obj *)0);
  2437.         } else {
  2438.             while (!(litter[i = rn2(9)] & INSHOP));
  2439.             remove_object(otmp);
  2440.             place_object(otmp, x+horiz(i), y+vert(i));
  2441.             litter[i] |= NEED_UPDATE;
  2442.         }
  2443.     }
  2444.     block_point(x, y);
  2445.     if(IS_DOOR(tmp_dam->typ)) {
  2446.         levl[x][y].doormask = D_CLOSED; /* arbitrary */
  2447.         newsym(x, y);
  2448.     } else {
  2449.         levl[x][y].doormask = D_NODOOR;
  2450.         if (IS_WALL(tmp_dam->typ) && cansee(x, y)) {
  2451.         /* Player sees actual repair process, so they KNOW it's a wall */
  2452.         levl[x][y].seen = 1;
  2453.         newsym(x, y);
  2454.         } else if (levl[x][y].seen) {
  2455.         /* Force a display update */
  2456.         levl[x][y].diggable |= W_REPAIRED;
  2457.         }
  2458.     }
  2459.     for (i = 0; i < 9; i++)
  2460.         if (litter[i] & NEED_UPDATE)
  2461.         newsym(x+horiz(i), y+vert(i));
  2462.     return(2);
  2463. #undef NEED_UPDATE
  2464. #undef OPEN
  2465. #undef INSHOP
  2466. #undef vert
  2467. #undef horiz
  2468. }
  2469.  
  2470. /*
  2471.  * shk_move: return 1: moved  0: didn't  -1: let m_move do it  -2: died
  2472.  */
  2473. int
  2474. shk_move(shkp)
  2475. register struct monst *shkp;
  2476. {
  2477.     register xchar gx,gy,omx,omy;
  2478.     register int udist;
  2479.     register schar appr;
  2480.     register struct eshk *eshkp = ESHK(shkp);
  2481.     int z;
  2482.     boolean uondoor = FALSE, satdoor, avoid = FALSE, badinv;
  2483.  
  2484.     omx = shkp->mx;
  2485.     omy = shkp->my;
  2486.  
  2487.     if (inhishop(shkp))
  2488.         remove_damage(shkp, FALSE);
  2489.  
  2490.     if((udist = distu(omx,omy)) < 3 &&
  2491.        (shkp->data != &mons[PM_GRID_BUG] || (omx==u.ux || omy==u.uy))) {
  2492.         if(ANGRY(shkp) ||
  2493.            (Conflict && !resist(shkp, RING_CLASS, 0, 0))) {
  2494.             if(Displaced)
  2495.               Your("displaced image doesn't fool %s!",
  2496.                 mon_nam(shkp));
  2497.             (void) mattacku(shkp);
  2498.             return(0);
  2499.         }
  2500.         if(eshkp->following) {
  2501.             if(strncmp(eshkp->customer, plname, PL_NSIZ)) {
  2502.                 verbalize("Hello, %s!  I was looking for %s.",
  2503.                     plname, eshkp->customer);
  2504.                     eshkp->following = 0;
  2505.                 return(0);
  2506.             }
  2507.             if(moves > followmsg+4) {
  2508.                 verbalize("Hello, %s!  Didn't you forget to pay?",
  2509.                     plname);
  2510.                 followmsg = moves;
  2511.                 if (!rn2(4)) {
  2512.         pline ("%s doesn't like customers who don't pay.", Monnam(shkp));
  2513.                 rile_shk(shkp);
  2514.                 }
  2515.             }
  2516.             if(udist < 2)
  2517.                 return(0);
  2518.         }
  2519.     }
  2520.  
  2521.     appr = 1;
  2522.     gx = eshkp->shk.x;
  2523.     gy = eshkp->shk.y;
  2524.     satdoor = (gx == omx && gy == omy);
  2525.     if(eshkp->following || ((z = holetime()) >= 0 && z*z <= udist)){
  2526.         if(udist > 4)
  2527.             return(-1);    /* leave it to m_move */
  2528.         gx = u.ux;
  2529.         gy = u.uy;
  2530.     } else if(ANGRY(shkp)) {
  2531.         /* Move towards the hero if the shopkeeper can see him. */
  2532.         if(shkp->mcansee && m_canseeu(shkp)) {
  2533.             gx = u.ux;
  2534.             gy = u.uy;
  2535.         }
  2536.         avoid = FALSE;
  2537.     } else {
  2538. #define    GDIST(x,y)    (dist2(x,y,gx,gy))
  2539.         if(Invis) {
  2540.             avoid = FALSE;
  2541.         } else {
  2542.             uondoor = (u.ux == eshkp->shd.x && u.uy == eshkp->shd.y);
  2543.             if(uondoor) {
  2544.             badinv = (!!carrying(PICK_AXE));
  2545.             if(satdoor && badinv)
  2546.                 return(0);
  2547.             avoid = !badinv;
  2548.             } else {
  2549.             avoid = (*u.ushops && distu(gx,gy) > 8);
  2550.             badinv = FALSE;
  2551.             }
  2552.  
  2553.             if(((!eshkp->robbed && !eshkp->billct && !eshkp->debit)
  2554.             || avoid) && GDIST(omx,omy) < 3) {
  2555.             if (!badinv && !onlineu(omx,omy))
  2556.                 return(0);
  2557.             if(satdoor)
  2558.                 appr = gx = gy = 0;
  2559.             }
  2560.         }
  2561.     }
  2562.  
  2563.     return(move_special(shkp,inhishop(shkp),
  2564.                 appr,uondoor,avoid,omx,omy,gx,gy));
  2565. }
  2566.  
  2567. /* for use in levl_follower (mondata.c) */
  2568. boolean
  2569. is_fshk(mtmp)
  2570. register struct monst *mtmp;
  2571. {
  2572.     return(mtmp->isshk && ESHK(mtmp)->following);
  2573. }
  2574.  
  2575. /* You are digging in the shop. */
  2576. void
  2577. shopdig(fall)
  2578. register int fall;
  2579. {
  2580.     register struct monst *shkp = shop_keeper(*u.ushops);
  2581.  
  2582.     if(!shkp) return;
  2583.  
  2584.     if(!inhishop(shkp)) {
  2585.     if (pl_character[0] == 'K') adjalign(-sgn(u.ualign.type));
  2586.     return;
  2587.     }
  2588.  
  2589.     if(!fall) {
  2590.     if(u.utraptype == TT_PIT)
  2591.         verbalize("Be careful, %s, or you might fall through the floor.",
  2592.         flags.female ? "madam" : "sir");
  2593.     else
  2594.         verbalize("%s, do not damage the floor here!",
  2595.             flags.female ? "Madam" : "Sir");
  2596.     if (pl_character[0] == 'K') adjalign(-sgn(u.ualign.type));
  2597.     } else if(!um_dist(shkp->mx, shkp->my, 5) &&
  2598.         !shkp->msleep && shkp->mcanmove &&
  2599.         (ESHK(shkp)->billct || ESHK(shkp)->debit)) {
  2600.         register struct obj *obj, *obj2;
  2601.  
  2602.         if (distu(shkp->mx, shkp->my) > 2) {
  2603.         mnexto(shkp);
  2604.         /* for some reason the shopkeeper can't come next to you */
  2605.         if (distu(shkp->mx, shkp->my) > 2) {
  2606.             pline("%s curses you in anger and frustration!",
  2607.                     shkname(shkp));
  2608.             rile_shk(shkp);
  2609.             return;
  2610.         } else pline("%s leaps, and grabs your backpack!",
  2611.                     shkname(shkp));
  2612.         } else pline("%s grabs your backpack!", shkname(shkp));
  2613.  
  2614.         for(obj = invent; obj; obj = obj2) {
  2615.         obj2 = obj->nobj;
  2616.         if(obj->owornmask) continue;
  2617. #ifdef WALKIES
  2618.         if(obj->otyp == LEASH && obj->leashmon) continue;
  2619. #endif
  2620.         freeinv(obj);
  2621.         obj->nobj = shkp->minvent;
  2622.         shkp->minvent = obj;
  2623.         subfrombill(obj, shkp);
  2624.         }
  2625.     }
  2626. }
  2627.  
  2628. #ifdef KOPS
  2629. STATIC_OVL void
  2630. makekops(mm)        /* returns the number of (all types of) Kops  made */
  2631. coord *mm;
  2632. {
  2633.     register int cnt = depth(&u.uz) + rnd(5);
  2634.     register int scnt = (cnt / 3) + 1;    /* at least one sarge */
  2635.     register int lcnt = (cnt / 6);        /* maybe a lieutenant */
  2636.     register int kcnt = (cnt / 9);        /* and maybe a kaptain */
  2637.  
  2638.     if (!(mons[PM_KEYSTONE_KOP].geno & G_EXTINCT)) {
  2639.         while(cnt--) {
  2640.         if (enexto(mm, mm->x, mm->y, &mons[PM_KEYSTONE_KOP]))
  2641.             (void) makemon(&mons[PM_KEYSTONE_KOP], mm->x, mm->y);
  2642.         }
  2643.     }
  2644.     if (!(mons[PM_KOP_SERGEANT].geno & G_EXTINCT)) {
  2645.         while(scnt--) {
  2646.         if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_SERGEANT]))
  2647.             (void) makemon(&mons[PM_KOP_SERGEANT], mm->x, mm->y);
  2648.         }
  2649.     }
  2650.     if (!(mons[PM_KOP_LIEUTENANT].geno & G_EXTINCT)) {
  2651.         while(lcnt--) {
  2652.         if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_LIEUTENANT]))
  2653.             (void) makemon(&mons[PM_KOP_LIEUTENANT], mm->x, mm->y);
  2654.         }
  2655.     }
  2656.     if (!(mons[PM_KOP_KAPTAIN].geno & G_EXTINCT)) {
  2657.         while(kcnt--) {
  2658.         if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_KAPTAIN]))
  2659.             (void) makemon(&mons[PM_KOP_KAPTAIN], mm->x, mm->y);
  2660.         }
  2661.     }
  2662. }
  2663. #endif    /* KOPS */
  2664.  
  2665. void
  2666. pay_for_damage(dmgstr)
  2667. const char *dmgstr;
  2668. {
  2669.     register struct monst *shkp = (struct monst *)0;
  2670.     char shops_affected[5];
  2671.     register boolean uinshp = (*u.ushops != '\0');
  2672.     char qbuf[80];
  2673.     register xchar x, y;
  2674.     register boolean dugwall = !strcmp(dmgstr, "dig into");
  2675.     struct damage *tmp_dam, *appear_here = 0;
  2676.     /* any number >= (80*80)+(24*24) would do, actually */
  2677.     long cost_of_damage = 0L;
  2678.     unsigned int nearest_shk = 7000, nearest_damage = 7000;
  2679.     int picks = 0;
  2680.  
  2681.     for (tmp_dam = level.damagelist;
  2682.          (tmp_dam && (tmp_dam->when == monstermoves));
  2683.          tmp_dam = tmp_dam->next) {
  2684.         char *shp;
  2685.  
  2686.         if (!tmp_dam->cost)
  2687.         continue;
  2688.         cost_of_damage += tmp_dam->cost;
  2689.         Strcpy(shops_affected,
  2690.            in_rooms(tmp_dam->place.x, tmp_dam->place.y, SHOPBASE));
  2691.         for (shp = shops_affected; *shp; shp++) {
  2692.         struct monst *tmp_shk;
  2693.         unsigned int shk_distance;
  2694.  
  2695.         if (!(tmp_shk = shop_keeper(*shp)))
  2696.             continue;
  2697.         if (tmp_shk == shkp) {
  2698.             unsigned int damage_distance =
  2699.                    distu(tmp_dam->place.x, tmp_dam->place.y);
  2700.  
  2701.             if (damage_distance < nearest_damage) {
  2702.             nearest_damage = damage_distance;
  2703.             appear_here = tmp_dam;
  2704.             }
  2705.             continue;
  2706.         }
  2707.         if (!inhishop(tmp_shk))
  2708.             continue;
  2709.         shk_distance = distu(tmp_shk->mx, tmp_shk->my);
  2710.         if (shk_distance > nearest_shk)
  2711.             continue;
  2712.         if ((shk_distance == nearest_shk) && picks) {
  2713.             if (rn2(++picks))
  2714.             continue;
  2715.         } else
  2716.             picks = 1;
  2717.         shkp = tmp_shk;
  2718.         nearest_shk = shk_distance;
  2719.         appear_here = tmp_dam;
  2720.         nearest_damage = distu(tmp_dam->place.x, tmp_dam->place.y);
  2721.         }
  2722.     }
  2723.  
  2724.     if (!cost_of_damage || !shkp)
  2725.         return;
  2726.  
  2727.     x = appear_here->place.x;
  2728.     y = appear_here->place.y;
  2729.  
  2730.     /* not the best introduction to the shk... */
  2731.     (void) strncpy(ESHK(shkp)->customer,plname,PL_NSIZ);
  2732.  
  2733.     /* if the shk is already on the war path, be sure it's all out */
  2734.     if(ANGRY(shkp) || ESHK(shkp)->following) {
  2735.         hot_pursuit(shkp);
  2736.         return;
  2737.     }
  2738.  
  2739.     /* if the shk is not in their shop.. */
  2740.     if(!*in_rooms(shkp->mx,shkp->my,SHOPBASE)) {
  2741.         if(!cansee(shkp->mx, shkp->my))
  2742.             return;
  2743.         goto getcad;
  2744.     }
  2745.  
  2746.     if(uinshp) {
  2747.         if(um_dist(shkp->mx, shkp->my, 1) &&
  2748.             !um_dist(shkp->mx, shkp->my, 3)) {
  2749.             pline("%s leaps towards you!", shkname(shkp));
  2750.             mnexto(shkp);
  2751.         }
  2752.         if(um_dist(shkp->mx, shkp->my, 1)) goto getcad;
  2753.     } else {
  2754.         /*
  2755.          * Make shkp show up at the door.  Effect:  If there is a monster
  2756.          * in the doorway, have the hero hear the shopkeeper yell a bit,
  2757.          * pause, then have the shopkeeper appear at the door, having
  2758.          * yanked the hapless critter out of the way.
  2759.          */
  2760.         if (MON_AT(x, y)) {
  2761.         if(flags.soundok) {
  2762.             You("hear an angry voice:");
  2763.             verbalize("Out of my way, scum!");
  2764.             wait_synch();
  2765. #if defined(UNIX) || defined(VMS)
  2766. # if defined(SYSV) || defined(ULTRIX) || defined(VMS)
  2767.             (void)
  2768. # endif
  2769.             sleep(1);
  2770. #endif
  2771.         }
  2772.         }
  2773.         (void) mnearto(shkp, x, y, TRUE);
  2774.     }
  2775.  
  2776.     if((um_dist(x, y, 1) && !uinshp) ||
  2777.             (u.ugold + ESHK(shkp)->credit) < cost_of_damage
  2778.                 || !rn2(50)) {
  2779.         if(um_dist(x, y, 1) && !uinshp) {
  2780.             pline("%s shouts:", shkname(shkp));
  2781.             verbalize("Who dared %s my %s?", dmgstr,
  2782.                      dugwall ? "shop" : "door");
  2783.         } else {
  2784. getcad:
  2785.             verbalize("How dare you %s my %s?", dmgstr,
  2786.                      dugwall ? "shop" : "door");
  2787.         }
  2788.         hot_pursuit(shkp);
  2789.         return;
  2790.     }
  2791.  
  2792.     if(Invis) Your("invisibility does not fool %s!", shkname(shkp));
  2793.     Sprintf(qbuf,"\"Cad!  You did %ld zorkmids worth of damage!\"  Pay? ",
  2794.          cost_of_damage);
  2795.     if(yn(qbuf) != 'n') {
  2796.         cost_of_damage = check_credit(cost_of_damage, shkp);
  2797.         u.ugold -= cost_of_damage;
  2798.         shkp->mgold += cost_of_damage;
  2799.         flags.botl = 1;
  2800.         pline("Mollified, %s accepts your restitution.",
  2801.             shkname(shkp));
  2802.         /* move shk back to his home loc */
  2803.         home_shk(shkp, FALSE);
  2804.         pacify_shk(shkp);
  2805.     } else {
  2806.         verbalize("Oh, yes!  You'll pay!");
  2807.         hot_pursuit(shkp);
  2808.         adjalign(-sgn(u.ualign.type));
  2809.     }
  2810. }
  2811.  
  2812. /* called in dokick.c when we kick an object that might be in a store */
  2813. boolean
  2814. costly_spot(x, y)
  2815. register xchar x, y;
  2816. {
  2817.     register struct monst *shkp;
  2818.  
  2819.     if (!level.flags.has_shop) return FALSE;
  2820.     shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
  2821.     if(!shkp || !inhishop(shkp)) return(FALSE);
  2822.  
  2823.     return(inside_shop(x, y) &&
  2824.         !(x == ESHK(shkp)->shk.x &&
  2825.             y == ESHK(shkp)->shk.y));
  2826. }
  2827.  
  2828. /* called by dotalk(sounds.c) when #chatting; returns obj if location
  2829.    contains shop goods and shopkeeper is willing & able to speak */
  2830. struct obj *
  2831. shop_object(x, y)
  2832. register xchar x, y;
  2833. {
  2834.     register struct obj *otmp;
  2835.     register struct monst *shkp;
  2836.  
  2837.     if(!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) || !inhishop(shkp))
  2838.     return(struct obj *)0;
  2839.  
  2840.     for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
  2841.     if (otmp->otyp != GOLD_PIECE)
  2842.         break;
  2843.     /* note: otmp might have ->no_charge set, but that's ok */
  2844.     return (otmp && costly_spot(x, y) && NOTANGRY(shkp)
  2845.         && !shkp->msleep && !shkp->mfrozen)
  2846.         ? otmp : (struct obj *)0;
  2847. }
  2848.  
  2849. /* give price quotes for all objects linked to this one (ie, on this spot) */
  2850. void
  2851. price_quote(first_obj)
  2852. register struct obj *first_obj;
  2853. {
  2854.     register struct obj *otmp;
  2855.     char buf[BUFSZ], price[40];
  2856.     long cost;
  2857.     int cnt = 0;
  2858.     winid tmpwin;
  2859.  
  2860.     tmpwin = create_nhwindow(NHW_MENU);
  2861.     putstr(tmpwin, 0, "Fine goods for sale:");
  2862.     putstr(tmpwin, 0, "");
  2863.     for (otmp = first_obj; otmp; otmp = otmp->nexthere) {
  2864.     if (otmp->otyp == GOLD_PIECE) {
  2865.      /* if (otmp == first_obj)  first_obj = otmp->nexthere; */
  2866.         continue;    /* don't quote a price on this */
  2867.     } else if (otmp->no_charge) {
  2868.         Strcpy(price, "no charge");
  2869.     } else {
  2870.         cost = get_cost(otmp, (struct monst *)0);
  2871.         Sprintf(price, "%ld zorkmid%s%s", cost, plur(cost),
  2872.             otmp->quan > 1L ? " each" : "");
  2873.     }
  2874.     Sprintf(buf, "%s, %s", doname(otmp), price);
  2875.     putstr(tmpwin, 0, buf),  cnt++;
  2876.     }
  2877.     if (cnt > 1) {
  2878.     display_nhwindow(tmpwin, TRUE);
  2879.     } else if (cnt == 1) {
  2880.     cost = get_cost(first_obj, (struct monst *)0);
  2881.     pline("%s, price %ld zorkmid%s%s%s", doname(first_obj),
  2882.         cost, plur(cost), first_obj->quan > 1L ? " each" : "",
  2883.         shk_embellish(first_obj, cost));
  2884.     }
  2885.     destroy_nhwindow(tmpwin);
  2886. }
  2887.  
  2888. static const char *
  2889. shk_embellish(itm, cost)
  2890. register struct obj *itm;
  2891. long cost;
  2892. {
  2893.     if (!rn2(3)) {
  2894.     register int o, choice = rn2(5);
  2895.     if (choice == 0) choice = (cost < 100L ? 1 : cost < 500L ? 2 : 3);
  2896.     switch (choice) {
  2897.         case 4:
  2898.         if (cost < 10L) break; else o = itm->oclass;
  2899.         if (o == FOOD_CLASS) return ", gourmets' delight!";
  2900.         if (objects[itm->otyp].oc_name_known
  2901.             ? objects[itm->otyp].oc_magic
  2902.             : (o == AMULET_CLASS || o == RING_CLASS   ||
  2903.                o == WAND_CLASS   || o == POTION_CLASS ||
  2904.                o == SCROLL_CLASS || o == SPBOOK_CLASS))
  2905.             return ", painstakingly developed!";
  2906.         return ", superb craftsmanship!";
  2907.         case 3: return ", finest quality.";
  2908.         case 2: return ", an excellent choice.";
  2909.         case 1: return ", a real bargain.";
  2910.        default: break;
  2911.     }
  2912.     } else if (itm->oartifact) {
  2913.     return ", one of a kind!";
  2914.     }
  2915.     return ".";
  2916. }
  2917.  
  2918. #ifdef KOPS
  2919. static void
  2920. kops_gone(silent)
  2921. register boolean silent;
  2922. {
  2923.     register int cnt = 0;
  2924.     register struct monst *mtmp, *mtmp2;
  2925.  
  2926.     /* turn off automatic resurrection of kops */
  2927.     allow_kops = FALSE;
  2928.  
  2929.     for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  2930.         mtmp2 = mtmp->nmon;
  2931.         if(mtmp->data->mlet == S_KOP) {
  2932.             mongone(mtmp);
  2933.             cnt++;
  2934.         }
  2935.     }
  2936.     if(cnt && !silent)
  2937.         pline("The Kops (disappointed) disappear into thin air.");
  2938.     allow_kops = TRUE;
  2939. }
  2940. #endif    /* KOPS */
  2941.  
  2942. static long
  2943. cost_per_charge(otmp)
  2944. register struct obj *otmp;
  2945. {
  2946.     register long tmp = 0L;
  2947.     register struct monst *shkp = shop_keeper(*u.ushops);
  2948.  
  2949.     if(!shkp || !inhishop(shkp)) return(0L); /* insurance */
  2950.     tmp = get_cost(otmp, shkp);
  2951.  
  2952.     /* The idea is to make the exhaustive use of */
  2953.     /* an unpaid item more expensive than buying */
  2954.     /* it outright.                     */
  2955.     if(otmp->otyp == MAGIC_LAMP) {             /* 1 */
  2956.         tmp += tmp / 3L;
  2957.     } else if(otmp->otyp == MAGIC_MARKER) {         /* 70 - 100 */
  2958.         /* no way to determine in advance   */
  2959.         /* how many charges will be wasted. */
  2960.         /* so, arbitrarily, one half of the */
  2961.         /* price per use.            */
  2962.         tmp /= 2L;
  2963.     } else if(otmp->otyp == BAG_OF_TRICKS ||     /* 1 - 20 */
  2964.           otmp->otyp == HORN_OF_PLENTY) {
  2965.         tmp /= 5L;
  2966.     } else if(otmp->otyp == CRYSTAL_BALL ||         /* 1 - 5 */
  2967.           otmp->otyp == OIL_LAMP ||         /* 1 - 10 */
  2968.           otmp->otyp == BRASS_LANTERN ||
  2969.          (otmp->otyp >= MAGIC_FLUTE &&
  2970.           otmp->otyp <= DRUM_OF_EARTHQUAKE) ||     /* 5 - 9 */
  2971.           otmp->oclass == WAND_CLASS) {         /* 3 - 11 */
  2972.             if (otmp->spe > 1) tmp /= 4L;
  2973.     } else if (otmp->oclass == SPBOOK_CLASS) {
  2974.             tmp -= tmp / 5L;
  2975.     }
  2976.     return(tmp);
  2977. }
  2978.  
  2979. /* for using charges of unpaid objects */
  2980. void
  2981. check_unpaid(otmp)
  2982. register struct obj *otmp;
  2983. {
  2984.     if(!*u.ushops) return;
  2985.  
  2986.     if(otmp->oclass != SPBOOK_CLASS && otmp->spe <= 0) return;
  2987.  
  2988.     if(otmp->unpaid) {
  2989.         register long tmp = cost_per_charge(otmp);
  2990.         register struct monst *shkp = shop_keeper(*u.ushops);
  2991.  
  2992.         if(!shkp || !inhishop(shkp)) return;
  2993.  
  2994.         if(otmp->oclass == SPBOOK_CLASS && tmp > 0L)
  2995.             pline("\"%sYou owe%s %ld zorkmids.\"",
  2996.             rn2(2) ? "This is no free library, cad!  " : "",
  2997.             ESHK(shkp)->debit > 0L ? " additional" : "", tmp);
  2998.         ESHK(shkp)->debit += tmp;
  2999.         exercise(A_WIS, TRUE);        /* you just got info */
  3000.     }
  3001. }
  3002.  
  3003. void
  3004. costly_gold(x, y, amount)
  3005. register xchar x, y;
  3006. register long amount;
  3007. {
  3008.     register long delta;
  3009.     register struct monst *shkp;
  3010.     register struct eshk *eshkp;
  3011.  
  3012.     if(!costly_spot(x, y)) return;
  3013.     /* shkp now guaranteed to exist by costly_spot() */
  3014.     shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
  3015.  
  3016.     eshkp = ESHK(shkp);
  3017.     if(eshkp->credit >= amount) {
  3018.         if(eshkp->credit > amount)
  3019.         Your("credit is reduced by %ld zorkmid%s.",
  3020.                     amount, plur(amount));
  3021.         else Your("credit is erased.");
  3022.         eshkp->credit -= amount;
  3023.     } else {
  3024.         delta = amount - eshkp->credit;
  3025.         if(eshkp->credit)
  3026.         Your("credit is erased.");
  3027.         if(eshkp->debit)
  3028.         Your("debt increases by %ld zorkmid%s.",
  3029.                     delta, plur(delta));
  3030.         else You("owe %s %ld zorkmid%s.",
  3031.                 shkname(shkp), delta, plur(delta));
  3032.         eshkp->debit += delta;
  3033.         eshkp->loan += delta;
  3034.         eshkp->credit = 0L;
  3035.     }
  3036. }
  3037.  
  3038. /* used in domove to block diagonal shop-exit */
  3039. /* x,y should always be a door */
  3040. boolean
  3041. block_door(x,y)
  3042. register xchar x, y;
  3043. {
  3044.     register int roomno = *in_rooms(x, y, SHOPBASE);
  3045.     register struct monst *shkp;
  3046.  
  3047.     if(roomno < 0 || !IS_SHOP(roomno)) return(FALSE);
  3048.     if(!IS_DOOR(levl[x][y].typ)) return(FALSE);
  3049.     if(roomno != *u.ushops) return(FALSE);
  3050.  
  3051.     if(!(shkp = shop_keeper((char)roomno)) || !inhishop(shkp))
  3052.         return(FALSE);
  3053.  
  3054.     if(shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y
  3055.         /* Actually, the shk should be made to block _any_
  3056.          * door, including a door the player digs, if the
  3057.          * shk is within a 'jumping' distance.
  3058.          */
  3059.         && ESHK(shkp)->shd.x == x && ESHK(shkp)->shd.y == y
  3060.         && shkp->mcanmove && !shkp->msleep
  3061.         && (ESHK(shkp)->debit || ESHK(shkp)->billct ||
  3062.         ESHK(shkp)->robbed)) {
  3063.         pline("%s%s blocks your way!", shkname(shkp),
  3064.                 Invis ? " senses your motion and" : "");
  3065.         return(TRUE);
  3066.     }
  3067.     return(FALSE);
  3068. }
  3069.  
  3070. /* used in domove to block diagonal shop-entry */
  3071. /* u.ux, u.uy should always be a door */
  3072. boolean
  3073. block_entry(x,y)
  3074. register xchar x, y;
  3075. {
  3076.     register xchar sx, sy;
  3077.     register int roomno;
  3078.     register struct monst *shkp;
  3079.  
  3080.     if(!(IS_DOOR(levl[u.ux][u.uy].typ) &&
  3081.         levl[u.ux][u.uy].doormask == D_BROKEN)) return(FALSE);
  3082.  
  3083.     roomno = *in_rooms(x, y, SHOPBASE);
  3084.     if(roomno < 0 || !IS_SHOP(roomno)) return(FALSE);
  3085.     if(!(shkp = shop_keeper((char)roomno)) || !inhishop(shkp))
  3086.         return(FALSE);
  3087.  
  3088.     if(ESHK(shkp)->shd.x != u.ux || ESHK(shkp)->shd.y != u.uy)
  3089.         return(FALSE);
  3090.  
  3091.     sx = ESHK(shkp)->shk.x;
  3092.     sy = ESHK(shkp)->shk.y;
  3093.  
  3094.     if(shkp->mx == sx && shkp->my == sy
  3095.         && shkp->mcanmove && !shkp->msleep
  3096.         && (x == sx-1 || x == sx+1 || y == sy-1 || y == sy+1)
  3097.         && (Invis || carrying(PICK_AXE))
  3098.       ) {
  3099.         pline("%s%s blocks your way!", shkname(shkp),
  3100.                 Invis ? " senses your motion and" : "");
  3101.         return(TRUE);
  3102.     }
  3103.     return(FALSE);
  3104. }
  3105.  
  3106. #endif /* OVLB */
  3107.  
  3108. /*shk.c*/
  3109.